What we are talking is about the difference between “>/dev/null 2>&1″ and “2>&1 >/dev/null”.
A. “>/dev/null 2>&1″:
- redirects stdout(1) to the file /dev/null
- THEN redirects stderr(2) to stdout(1)
B. “2>&1 >/dev/null”:
- redirects stderr(2) to stdout(1)
- THEN redirects stdout to the file /dev/null
Now, that all sounds reasonable. It also sound like both statements accomplish the same thing…. but, actually, they don’t. The assignment of descriptors is absolute. If you assign stdout to /dev/null, then later assignments follow that same path. If you assign stderr to stdout, all stderr messages will go to the stdout device. If you later assign stdout messages to /dev/null, the messages going to stderr will still get sent to the stdout device because “>/dev/null” doesn’t repoint the device, it repoints the stream.
shelley:~% cat hi.c
#include "unistd.h"
main()
{
write(1, "Hello ", 6);
write(2, "World\n", 6);
}
shelley:~% gcc -o hi hi.c
shelley:~% ./hi
Hello World
shelley:~% ./hi >/dev/null
World
shelley:~% ./hi >/dev/null 2>&1
shelley:~% ./hi 2>&1 >/dev/null
World
Done.