7

I have checked couple of relevant posts regarding this in stackoverflow and other sources regarding the usage of 2>&1.

Unfortunately so far have not get my head around it completely.

I understand that 2 is the stderr and 1 is the stdout and we are combining with the 2>&1.

But my question is what is difference between:

1. mycommand > /dev/null       
2. mycommand 2> /dev/null      
3. mycommand > /dev/null 2>&1  

I was thinking:

  1. will redirect stdout and stderr to /dev/null
  2. will redirect stderr to /dev/null
  3. will redirect stdout and stderr to /dev/null

Relevant posts:

Community
  • 1
  • 1
Exploring
  • 2,493
  • 11
  • 56
  • 97

4 Answers4

13

See this:

mycommand > /dev/null

it will redirect channel 1 (which is stdout) of mycommand to /dev/null

mycommand 2> /dev/null

it will redirect channel 2 (which is stderr) to /dev/null

mycommand > /dev/null 2>&1

it will redirect channel 1 to /dev/null and then bind channel 2 (stderr) to channel 1 (stdout). Both will go into /dev/null

There is another one (just to complete)

mycommand 2>&1 > /dev/null

In this second case, I bind (the child's) stderr to stdout (of the parent) and then I find the child's stdout to /dev/null. The result is that you now get the child's stderr output on stdout and the stdout goes to the file. This is useful for processing stderr in a pipe, for example. (see this answer)

Community
  • 1
  • 1
chaos
  • 8,162
  • 3
  • 33
  • 40
  • So `mycommand > /dev/null 2>&1` and `mycommand 2>&1 > /dev/null` will be same-right? – Exploring Dec 10 '13 at 12:22
  • Besides why we are saying (the child's) stderr to stdout (of the parent). I thought you are binding parents stderr to the stdout of the parent and then stdout of parent is going to the dev/null. I shall check the link you have attached. – Exploring Dec 10 '13 at 12:26
  • 5
    @Baishakh No, `cmd > /dev/null 2>&1` is very different than `cmd 2>&1 /dev/null`. The first directs both streams to /dev/null. The second directs stdout to /dev/null and stderr is sent to whatever stdout was before it was redirected to /dev/null. By 'the parent', chaos is referring to the shell that is parsing the command line, and 'the child' is the command being invoked. – William Pursell Dec 10 '13 at 12:54
  • I am now getting confused with the order of the command line. `mycommand > /dev/null 2>&1`. I thought IO redirection is left to right. And in this case we are completing the redirection to /dev/null at first and then doing the 2>&1. – Exploring Dec 10 '13 at 13:00
  • 5
    @Baishakh, think of `x 2>&1 >/dev/null` this way: file descriptor 1 originally points to a physical file, say /dev/stdout. `2>&1` redirects fd 2 to whatever fd 1 points at (/dev/stdout). Then fd 1 is redirected to /dev/null. That last redirection does *not* affect what fd 2 is now pointing at. So, left to right is correct. `x >/dev/null 2>&1` works similarly: first fd 1 is redirected to /dev/null, then fd 2 is redirected to whatever fd 1 is currently pointing at. – glenn jackman Feb 03 '14 at 22:25
4

(errfile doesn't exist)

$ cat errfile
cat: 0652-050 Cannot open errfile.

$ cat errfile > /tmp/stream.out
cat: 0652-050 Cannot open errfile.


$ cat errfile > /tmp/stream.out 2>&1

$ cat /tmp/stream.out
cat: 0652-050 Cannot open errfile.

($ rm /tmp/stream.out)

$ cat errfile 2>&1 > /tmp/stream.out
cat: 0652-050 Cannot open errfile.

$ cat /tmp/stream.out

$

Order is thus important and 2>&1 1>out is different than 1>out 2>&1 due to stream redirection at shell interpretation. You shoud redirect in "reverse" order. stdout > final than source > stdout

NeronLeVelu
  • 9,908
  • 1
  • 23
  • 43
  • I am now getting confused with the order of the command line. I thought IO redirection is left to right – Exploring Dec 10 '13 at 16:31
3

Try these to get the differences:

echo "stderr" > /dev/fd/2 | >/dev/null
stderr
echo "stdout" > /dev/fd/1 | >/dev/null

both commands redirected to /dev/null but in first one we're writing to stderr which prints stderr but in second one it prints nothing

vahid abdi
  • 9,636
  • 4
  • 29
  • 35
0

1: redirect STDOUT to /dev/null, you use default file descriptor in this case, e.g. command [default]> filename, the default file descriptor is STDOUT.

2: redirect STDERR to /dev/null

3: redirect STDOUT to /dev/null and redirect STDERROR to STDOUT, which means both STDOUT and STDERROR will be redirected to /dev/null

Hope the tips make you clear.

0, 1, 2...9 are file descriptors in bash. 0 stands for stdin, 1 stands for stdout, 2 stands for stderror. 3~9 is spare for any other temporary usage.

Any file descriptor can be redirected to other file descriptor or file by using operator > or >>(append).

Usage: >

Please reference to http://www.tldp.org/LDP/abs/html/io-redirection.html

Quintus.Zhou
  • 1,013
  • 10
  • 13