2

I am trying to understand a command like

[command] > /dev/null 2>&1

If I understand this correctly, the output of the command is redirected to /dev/null and then the stderr (file descriptor 2) is redirected to stdout (file descriptor 1)

The end result is, only errors of [command] will be output

To understand this, I executed the following commands:

bash-3.2$ echo "Hello World" 1>&2
Hello World

Here, I am echoing "Hello World" and redirecting it to stderr. And now I run the following:

bash-3.2$ echo "Hello World" 1>&2 2>&1
Hello World

I am taking the stderr and redirecting it to stdout. And as expected, it prints Hello World

Now I run this

bash-3.2$ echo "Hello World" 1>&2 1>&1
Hello World

What I am trying to do is to printout stdout. However, there is no stdout since I redirected it to stderr.

So why is it printing Hello World? I would have expected it to print nothing.

madu
  • 125

1 Answers1

2
echo "Hello World" 1>&2 1>&1

redirects file descriptor 1 (standard out) to whatever file descriptor 2 (standard error) is pointing at, and then redirects file descriptor 1 to itself. All the output thus goes to standard error, but you haven’t changed that — so it all goes to your current terminal.

To print nothing, you need to redirect standard error:

(echo "Hello World" 1>&2 1>&1) 2> /dev/null

or equivalently,

echo "Hello World" 2>/dev/null 1>&2

Your interpretation of

[command] > /dev/null 2>&1

isn’t accurate: > /dev/null redirects standard output to /dev/null, and then redirects standard error to what standard output is currently pointing at, /dev/null. So all the output is discarded.

See What are the shell's control and redirection operators? for details.

Stephen Kitt
  • 434,908