Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do we do '< /dev/null' in certain shell commands

Tags:

bash

shell

A shell construct confused me recently, what's the difference between

while ! nc -z $HOST $PORT >/dev/null 2>&1 < /dev/null; do 

and

while ! nc -z $HOST $PORT >/dev/null 2>&1 ; do
like image 281
Ausar Avatar asked May 10 '18 07:05

Ausar


1 Answers

The purpose of < /dev/null is to send EOF to a program immediately when tries to read from its standard input. It also means that the standard input is cut from receiving input from any other sources e.g. terminal.

The /dev/null is a special device in Unix which consumes everything written to it but signals EOF whenever commands tries to read from it without actually providing any actual data to read from.

The re-directions >/dev/null 2>&1 mean that redirect all standard output produced by the command to the null device which it consumes and redirect all error stream output(2) to the console.

Answering to another OP's question

So what happens if I don't send EOF to nc? I have try it and the script also worked

Nothing is expected to happen. By doing </dev/null we just signal the nc to not expect to read anything from standard input.


Another classic example of why you would need this is when using ssh if incorrectly used with a while loop. Consider an example, if you have a file servers.txt containing a list of server names and want to do an operation over ssh for all the hosts. You would do something like

while read -r server; do
    ssh "$server" "uname -a"
done < servers.txt

You could think this being pretty straight forward with nothing expected to go wrong. But it does!

ssh will read from standard input. You have already added a read command with an input redirection over the file, so it also reads from standard input. The logic will be screwed up because after the first read command, the ssh will end up swallowing rest of the standard input which is undesired in your case.

So what do we do? We close the standard input of ssh by doing </dev/null as

ssh "$server" "uname -a" < /dev/null
like image 190
Inian Avatar answered Nov 14 '22 21:11

Inian