Writing outputs to log file and console
I tried joonty's answer, but I also got the
exec: 1: not found
error. This is what works best for me (confirmed to work in zsh also):
#!/bin/bash
LOG_FILE=/tmp/both.log
exec > >(tee ${LOG_FILE}) 2>&1
echo "this is stdout"
chmmm 77 /makeError
The file /tmp/both.log afterwards contains
this is stdout
chmmm command not found
The /tmp/both.log is appended unless you remove the -a from tee.
Hint: >(...)
is a process substitution. It lets the exec
to the tee
command as if it were a file.
exec 3>&1 1>>${LOG_FILE} 2>&1
would send stdout and stderr output into the log file, but would also leave you with fd 3 connected to the console, so you can do
echo "Some console message" 1>&3
to write a message just to the console, or
echo "Some console and log file message" | tee /dev/fd/3
to write a message to both the console and the log file - tee
sends its output to both its own fd 1 (which here is the LOG_FILE
) and the file you told it to write to (which here is fd 3, i.e. the console).
Example:
exec 3>&1 1>>${LOG_FILE} 2>&1
echo "This is stdout"
echo "This is stderr" 1>&2
echo "This is the console (fd 3)" 1>&3
echo "This is both the log and the console" | tee /dev/fd/3
would print
This is the console (fd 3)
This is both the log and the console
on the console and put
This is stdout
This is stderr
This is both the log and the console
into the log file.