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).

4

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

  • 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 '15 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 '15 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. – glenn jackman Nov 11 '15 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 '15 at 12:21
  • @Xen2050 That is correct :-) For more information see wiki.bash-hackers.org/howto/redirection_tutorial – NZD Nov 11 '15 at 18:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.