" is however a bash-specific shortcut (redirect fd1 and fd2 together), and not generally recommended. The standard, portable redirection is this:
command >/dev/null 2>&1
I will say that the concept of file descriptors does take some time to learn properly. The main points that helped me to understand what was happening were these:
1) Every command has three file descriptors automatically set up; stdin (fd0, the input into the command), stdout (fd1, the main text output), and stderr (fd2, error messages or other text that's intended for display only, and doesn't "mix" with stdout). These are the numbers on the left side of the redirection arrow (no number = fd0 or fd1, depending on the arrow direction). These cannot be changed; they can only be connected to a different output (or input, for fd0).
2) The right side of the arrow can be either a file name or "&n
", in this context basically means "the same target location
that file descriptor n is currently set to". i.e. what it does not
mean is "send it to fdn".
3) Any pre-existing file descriptors are first inherited from the parent shell, and then the ones on the command line are set from left to right. Any redirection using "&n
" will naturally depend on what got set before it.
Thus "command >/dev/null 2>&1
", translated into regular speech, is "send the command's stdout content to /dev/null, then send it's stderr content to the same place that stdout is currently pointing (which is now /dev/null)". Both stdout and stderr end up going into the bitbucket.
"command 2>&1 >/dev/null
", on the other hand, means "send the command's stderr content to the same place that stdout is currently pointing (the screen, by default), then send it's stdout content to /dev/null. So the command's stderr messages end up going to the screen (but now as stdout content, so it will also pass through pipes, etc), and the original stdout content gets thrown away.
See here for the best explanation of file descriptors I've yet read: