5

What I want to achieve is redirect both normal message and error message to a file. But also print the error message to the console (only error message).

1 Answer 1

5

One (out of many) solutions is the following:

command 2>&1 1>logfile | tee -a logfile

Key:

`2>&1` redirect the output of STDERR to STDOUT
`1>logfile` redirect STDOUT (note: leaves STDERR unchanged)
`| tee -a logfile` append the redirected STDERR to the logfile

For more information, see the Bash Hackers Wiki

6
  • Before I think after redirect 2>&1, the 1 holds everything, no matter where your redirect the 1 later, STDERR goes together.
    – Enze Chi
    Nov 11, 2015 at 0:33
  • 3
    @EnzoChi The redirect 2>&1 tells bash to redirect STDERR to the same fd (file descriptor) as where STDOUT currently goes. It is not redirecting it to STDOUT. If you then redirect STDOUT (1>logfile), STDERR won't be affected, it will still be pointing to the same fd. The order of doing the redirections is important.
    – NZD
    Nov 11, 2015 at 0:42
  • 1
    can be slightly shortened: command 2> >(tee -a logfile) 1>>logfile -- stderr is redirected into a process substitution, and tee writes to stdout. No real benefit over your answer. Nov 11, 2015 at 1:00
  • 1
    So, 1 and 2 are just pointers, taking a program's stdout & stderr messages and normally putting them to terminal/screen, unless changed/redirected/piped. Making 2>&1 doesn't "attach" 2 to 1, but just attaches 2 to whatever 1 was pointing to, at that time...?
    – Xen2050
    Nov 11, 2015 at 12:21
  • @Xen2050 That is correct :-) For more information see wiki.bash-hackers.org/howto/redirection_tutorial
    – NZD
    Nov 11, 2015 at 18:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .