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

  • 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?

  • Kusalananda

    Kusalananda Correct answer

    2 years ago

    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.

    With the command "`utility 2>&1 | tee output.log`, do you mean to say that since 1 is being directed to tee, 2 is as well. Since tee duplicates the stream, the output is both displayed on the console as well as written to file? Hence the difference between `utility 2>&1 > output.log` and `utility 2>&1 | tee output.log` is `tee` in that it duplicates the stream. Would that be correct?

    With the examples of `utility 2>&1 > output.log | more_stuff` and `utility >ouput.log` | more_stuff`, is the difference that `more_stuff` has the standard error output to the console as an input `more_stuff`? Since in the second example, there is no output to the the console, there is essentially no input to `more_stuff`? If yes, that isn't clear since the preceding paragraph you note that standard output goes to the file and standard error goes to the console.

    @Motivated Your first comment seems correct to me, yes. As for the second comment: In the first command, `more_stuff` would receive what `utility` originally sent to its _error stream_ (but which was redirected to the standard output). Not because it would end up on the console if `more_stuff` wasn't there, but because it's going to the _standard output stream_. In the second command, `more_stuff` receives _nothing_ as there is no standard output from the left hand side of the pipeline. The error stream from `utility` would still end up on the console in the 2nd command.

    Thanks. Do you mean that because the command `utility > output.log | more_stuff` does not result in an output in the standard output stream from a standard error point of view?

    @Motivated Since the left hand side doesn't produce anything on standard output (it's redirected), no data will be sent over the pipe.

    Thanks. I wanted to clarify that when you say the left hand doesn't produce a result to standard output, it is because standard error isn't being redirected to standard output i.e. 2>&1 since the syntax is > output.log.

    Thanks for the answer. It'd be great if you could add a breakdown of what `utility >output.log 2>&1` does. I understand it outputs both stdout and stderr to the file, but not exactly why. You break down the other commands but not this one. Thanks.

    @Max I have expanded one of the sentences in the first part of the answer to include "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".

License under CC-BY-SA with attribution


Content dated before 6/26/2020 9:53 AM