This has always confused me. So I'll try to recapitulate what I understand in this mini-blog for my future reference.
In a Unix shell, 0 stands for stdin, 1 stands for stdout while 2 stands for stderr.
You can redirect stderr to stdout if you append this to your Unix command:
2>&1
Corollary, you can redirect stdout to stderr (which do not usually happen) by appending this otherwise:
1>&2
By default, when you redirect a stream, it redirects stdout. Which means the this command will log stdout to the the file (but not stderr):
$ echo "test string" >test.log
Building on this, if we want not only stdout but also stderr to the directed to test.log we issue this command:
$ echo "test string" >test.log 2>&1
The command reads from left to right (and the sequence is important as the first redirection takes precedence over the later redirection specification). And it should read: "redirect stdout to test.log, then redirect the stderr to the same place stdout is going (which is test.log)."
Now, in some cases, the sequence does not "seem" make any difference but in fact there's a subtle nuance introduced by the sequence like in doing so:
$ echo "test string" 2>&1 >test.log
In the above, it reads: "redirect stderr to the same place stdout is going (which is the console), then redirect stdout to test.log (but not stderr)." The net effect is that stderr is redirected to console but stdout is directed to test.log. The above is made more explicit by the equivalent command:
$ echo "test string" 2>&1 1>test.log
Now consider these two commands:
$ echo "test string" >/dev/null 2>&1
$ echo "test string" 2>&1 >/dev/null
The first reads: "redirect stdout to
/dev/null (meaning discard the bytes streamed to stdout), then redirect stderr to the same place stdout is going (which is now
/dev/null)." The end effect is that both stdout and stderr is discarded.
The second reads: "redirect stderr to the same place stdout is going (which is the console), then redirect stdout to
/dev/null (meaning discard the bytes streamed to stdout)." The end effect is that whilst stderr is printed on the console, stdout is discarded.
One link that really seems helpful is this:
http://wiki.bash-hackers.org/howto/redirection_tutorial