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
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
, the1
holds everything, no matter where your redirect the1
later, STDERR goes together.– Enze ChiNov 11, 2015 at 0:33 -
3@EnzoChi The redirect
2>&1
tells bash to redirect STDERR to the same fd (file descriptor) as where STDOUTcurrently
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.– NZDNov 11, 2015 at 0:42 -
1can 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 -
1So, 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...?– Xen2050Nov 11, 2015 at 12:21 -
@Xen2050 That is correct :-) For more information see wiki.bash-hackers.org/howto/redirection_tutorial– NZDNov 11, 2015 at 18:58