Difference between 2>&1 > output.log and 2>&1 | tee output.log

Editorial note

Please make sure to read the comments on this answer — derobert.


Original answer

2>&1 >output.log means first start sending all file handle 2 stuff (standard error) to file handle 1 (standard output) then send that to the file output.log. In other words, send standard error and standard output to the log file.

2>&1 | tee output.log is the same with the 2>&1 bit, it combines standard output and standard error on to the standard output stream. It then pipes that through the tee program which will send its standard input to its standard output (like cat) and also to the file. So it combines the two streams (error and output), then outputs that to the terminal and the file.

The bottom line is that the first sends stderr/stdout to the file, while the second sends it to both the file and standard output (which is probably the terminal unless you're inside another construct which has redirected standard output).

I mention that last possibility because you can have stuff like:

(echo hello | tee xyzzy.txt) >plugh.txt

where nothing ends up on the terminal.


Looking at the two commands separately:

utility 2>&1 >output.log 

Here, since redirections are processed in a left-to-right manner, the standard error stream would first be redirected to wherever the standard output stream goes (possibly to the console), and then the standard output stream would be redirected to a file. The standard error stream would not be redirected to that file.

The visible effect of this would be that you get what's produced on standard error on the screen and what's produced on standard output in the file.

utility 2>&1 | tee output.log

Here, you redirect standard error to the same place as the standard output stream. This means that both streams will be piped to the tee utility as a single intermingled output stream, and that this standard output data will be saved to the given file by tee. The data would additionally be reproduced by tee in the console (this is what tee does, it duplicates data streams).

Which ever one of these is used depends on what you'd like to achieve.

Note that you would not be able to reproduce the effect of the second pipeline with just > (as in utility >output.log 2>&1, which would save both standard output and error in the file by first redirecting standard output to the output.log file and then redirecting standard error to where standard output is now going). You would need to use tee to get the data in the console as well as in the output file.


Additional notes:

The visible effect of the first command,

utility 2>&1 >output.log 

would be the same as

utility >output.log

I.e., the standard output goes to the file and standard error goes to the console.

If a further processing step was added to the end of each of the above commands, there would be a big difference though:

utility 2>&1 >output.log | more_stuff

utility >output.log      | more_stuff

In the first pipeline, more_stuff would get what's originally the standard error stream from utility as its standard input data, while in the second pipeline, since it's only the resulting standard output stream that is ever sent across a pipe, the more_stuff part of the pipeline would get nothing to read on its standard input.


First command will do the another task:

After

2>&1 > output.log 

the old STDOUT will be saved (copied) in STDERR and then STDOUT will be redirected to file.

So, stdout will go to file and stderr will go to console.

And in

 2>&1 | tee output.log

both streams will be redirected to tee. Tee will duplicate any input to its stdout (the console in your case) and to file (output.log).

And there is another form of first:

    > output.log  2>&1

this will redirect both STDOUT and STDERR to the file.