2

This is normal redirection.

user@linux:~$ randomcommand
randomcommand: command not found
user@linux:~$ 

2>

user@linux:~$ randomcommand 2> /dev/null
user@linux:~$ 

&>

user@linux:~$ randomcommand &> /dev/null
user@linux:~$ 

However, it doesn't work when I tried to do the same with different command as shown below.

&>

user@linux:~$ > /dev/tcp/127.0.0.1/22 &> /dev/null && echo open || echo closed
bash: connect: Connection refused
bash: /dev/tcp/127.0.0.1/22: Connection refused
closed
user@linux:~$ 

2>

user@linux:~$ > /dev/tcp/127.0.0.1/22 2> /dev/null && echo open || echo closed
bash: connect: Connection refused
bash: /dev/tcp/127.0.0.1/22: Connection refused
closed
user@linux:~$ 

What's wrong with these syntax and how to fix it?

4

The error is output at the time bash is processing the > /dev/tcp/localhost/22 redirection, and at that point stderr hasn't been redirected yet. Just change the order of those two redirections:

if 2> /dev/null > /dev/tcp/127.0.0.1/22; then
  echo open
else
  echo closed
fi

Note that those /dev/tcp/host/port are not real files. bash (or ksh where that feature comes from) detects the fact that you're trying to redirect to those special files (you'll notice that if you change it to /dev/./tcp or /dev//tcp it no longer works) and instead of opening those files, creates a TCP socket and attempts to connect() it on the host and port. And it's when that connect fails that bash is reporting an error.

zsh has a ztcp builtin command instead (in the zsh/net/tcp module) which makes it a bit more intuitive and also allows more things like server side connections.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy