Я не мог заставить работать очень простую однострочную версию Денниса, так что вот гораздо более запутанный метод. Я бы попробовал его первым.
Как уже упоминалось, вы можете использовать exec для перенаправления стандартной ошибки и стандартной ошибки для всего сценария. Вот так:
exec > $LOGFILE 2>&1
Это выведет все stderr и stdout в $ LOGFILE.
Теперь, так как вы хотите, чтобы это отображалось на консоли, а также в лог-файле, вам также придется использовать именованный канал для exec для записи и для чтения.
(Однострочник Денниса технически тоже делает это, хотя, очевидно, по-другому). Сам канал создается с помощью mkfifo $PIPEFILE
. Затем сделайте следующее.
# Start tee writing to a logfile, but pulling its input from our named pipe.
tee $LOGFILE < $PIPEFILE &
# capture tee's process ID for the wait command.
TEEPID=$!
# redirect the rest of the stderr and stdout to our named pipe.
exec > $PIPEFILE 2>&1
echo "Make your commands here"
echo "All their standard out will get teed."
echo "So will their standard error" >&2
# close the stderr and stdout file descriptors.
exec 1>&- 2>&-
# Wait for tee to finish since now that other end of the pipe has closed.
wait $TEEPID
Если вы хотите быть тщательным, вы можете создать и уничтожить файл именованного канала в начале и конце вашего скрипта.
Для справки, я почерпнул большую часть этого из очень информативного поста в блоге случайного парня: (Архивная версия)