4

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.

terdon
  • 104,119

2 Answers2

9

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
terdon
  • 104,119
3

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"