STDOUT and STDERR redirection for nc

18,348

Solution 1

The problem has nothing to do with nc or netcat or any of their ilk. You are running two commands here, nc and grep, but only redirecting the output of grep. What you want to do is:

nc -zv 1.2.3.4 55  &>/dev/null

That, of course, would be pointless since if there's no output, you can't grep. That's what grep's -q flag is for:

   -q, --quiet, --silent
          Quiet;   do   not  write  anything  to  standard  output.   Exit
          immediately with zero status if any match is found, even  if  an
          error was detected.  Also see the -s or --no-messages option.

So, what you're after is something like this:

nc -zv 1.2.3.4 55 2>/dev/null | grep -q " open " && start_daemon

Or, if you need to parse stderr as well, this:

nc -zv 1.2.3.4 55  |& grep -q " open " && start_daemon

Solution 2

Managed to get the script running properly using netcat's nc's exit status, while running it without -v option. Anyway, it seems that netcat's netcat's output doesn't get piped into grep. I suppose it might be caused by some sort of forking.

UPDATE:

As terdon mentioned in a comment to his answer, part of output from nc / netcat is printed to stderr, part to stout. So merging these two files before piping to grep does the trick:

netcat -zvw1 1.2.3.4 55 2>&1 | grep "open"

Share:
18,348

Related videos on Youtube

Ricardo Beschieru
Author by

Ricardo Beschieru

Updated on September 18, 2022

Comments

  • Ricardo Beschieru
    Ricardo Beschieru over 1 year

    I am trying to make a watchdog bash script which has to check if the port is open, based on the exit status, otherwise should start the daemon. Problem is I can't manage to avoid the script outputting any information by redirecting STDOUT and STDERR.

    nc -zv 1.2.3.4 55 | grep " open " >/dev/null 2>&1
    

    or

    nc -zv 1.2.3.4 55 | grep " open " 2>&1 >/dev/null
    

    or

    nc -zv 1.2.3.4 55 | grep " open " &>/dev/null
    

    returns anyway

    'FQDN_hostname_or_domainname [1.2.3.4] 55 (?) open'
    

    Nevertheless, this combo works with other commands, such as netstat. Is it something about netcat, or maybe about bash syntax? Please let me know what I am getting wrong.

  • Ricardo Beschieru
    Ricardo Beschieru almost 8 years
    Seems that sdtout and stderr from netcat don't get piped into grep. While grepping "open", for example, netcat's output still gets displayed, even though was netcated a closed port, so there is no "open" in netcat's output message.
  • terdon
    terdon almost 8 years
    @RicardoBeschieru everything is piped, one way or the other. Worst case scenario, you might need to do something like (nc -zv 1.2.3.4 55 2>/dev/null) | grep ..., but that would be very surprising. What exact command are you running now?
  • Ricardo Beschieru
    Ricardo Beschieru almost 8 years
    I am running netcat -zvw1 1.2.3.4 55 | grep "open"
  • terdon
    terdon almost 8 years
    @RicardoBeschieru does nc -zv 1.2.3.4 55 2>&1 | grep open work?
  • Ricardo Beschieru
    Ricardo Beschieru almost 8 years
    Yes, it does. It seems this is one of the differences between nc and netcat . My bad. Still is a mystery why output from netcat doesn't get piped to grep.
  • terdon
    terdon almost 8 years
    @RicardoBeschieru sorry, I was on mobile. I meant try netcat -zvw1 1.2.3.4 55 2>&1 | grep "open". The thing is that some output is printed to stderr and some to stdout. If you just run command | grep foo, only stout is passed to grep. If you also want to grep stderr, you need 2>&1 or &|.
  • Ricardo Beschieru
    Ricardo Beschieru almost 8 years
    Yes, netcat -zvw1 1.2.3.4 55 2>&1 | grep "open" does work, so nc -zvw1 1.2.3.4 55 2>&1 | grep "open". Turns out there is no difference betweeen nc and netcat in this case. Thanks!