I know how to redirect stdout to a file:
exec > foo.log
echo test
this will put the 'test' into the foo.log file.
Now I want to redirect the output into the log file AND keep it on stdout
i.e. it can be done trivially from outside the script:
script | tee foo.log
but I want to do declare it within the script itself
I tried
exec | tee foo.log
but it didn't work.
Easy way to make a bash script log to syslog. The script output is available both through
/var/log/syslog
and through stderr. syslog will add useful metadata, including timestamps.Add this line at the top:
Alternatively, send the log to a separate file:
This requires
moreutils
(for thets
command, which adds timestamps).Neither of these is a perfect solution, but here are a couple things you could try:
or
The second one would leave a pipe file sitting around if something goes wrong with your script, which may or may not be a problem (i.e. maybe you could
rm
it in the parent shell afterwards).The accepted answer does not preserve STDERR as a separate file descriptor. That means
will not output
bar
to the terminal, only to the logfile, andwill output both
foo
andbar
to the terminal. Clearly that's not the behaviour a normal user is likely to expect. This can be fixed by using two separate tee processes both appending to the same log file:(Note that the above does not initially truncate the log file - if you want that behaviour you should add
to the top of the script.)
The POSIX.1-2008 specification of
tee(1)
requires that output is unbuffered, i.e. not even line-buffered, so in this case it is possible that STDOUT and STDERR could end up on the same line offoo.log
; however that could also happen on the terminal, so the log file will be a faithful reflection of what could be seen on the terminal, if not an exact mirror of it. If you want the STDOUT lines cleanly separated from the STDERR lines, consider using two log files, possibly with date stamp prefixes on each line to allow chronological reassembly later on.