Any process on UNIX can write its output to standard out, standard error or a file. All of these are handled by unix in the same way, so 'stdout' and 'stderr' are considered files. Every file on UNIX is written to using a 'file handle', also known as a 'file descriptor'. This tells the Operating System where the file is and other useful information.
For all processes, stdout has a file descriptor of '1' and stderr has a file descriptor of '2'. These reserved file desciptors are usually associated with the current terminal (or screen) of a process. So if you type 'ls' in an xterm, the output from the 'ls' process is sent to file descriptor '1' which is associated with your xterm.
%ls file*
file1 file2 file3
Equally, if 'ls' encounters any errors, the error text is sent to file descriptor '2', which is also linked with your xterm, so it appears in the same place.
%ls files*
files*: No such file or directory
However, if you wanted to put your information onto a pipe, such as:
ls file* | grep 2
file2
Then you have to remember that the only information that is passed along the pipe, in this case to the 'grep' process, is stdout, or file descriptor '1'. If you mis-typed the command as in the example above, then your error information would not be passed to the grep:
ls files* | grep 2
files*: No such file or directory
There are some cases when you WANT to be able to pass the error information on, for example you may be grep'ing for error messages.
In this case, you need to bind the output sent to stderr onto the same address as stdout. This is what the statement 2>&1 is doing. You might read the statement as:
"stderr (2) is bound (>) onto the address (&) of stdout (1)"
...and it can be used in the form:
command > file 2>&1
(notice that the bind is applied at the end of the line because it affects the whole preceeding process)
This example only works for bourne shell based shells, such as sh, bash and ksh. For csh, you need the more terse syntax:
command >& file
If you want to know more about redirection of file descriptors, you could try the man pages for the shell you are using, and also take a look at the man page for the exec command which gives you the ability to save and restore modified file descriptors.
Christian