Shell – Difference Between 2>&1 > output.log and 2>&1 | tee output.log

io-redirectionpipeshell

I wanted to know the difference between the following two commands

2>&1 > output.log 

and

2>&1 | tee output.log

I saw one of my colleague use second option to redirect. I know what 2>&1 does, my only question is what is the purpose of using tee where a simple redirection ">" operator can be used?

Best Answer

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.

Related Question