Я не мог заставить работать очень простую однострочную версию Денниса, так что вот гораздо более запутанный метод. Я бы попробовал его первым.
Как уже упоминалось, вы можете использовать exec для перенаправления стандартной ошибки и стандартной ошибки для всего сценария.
exec > $LOGFILE 2>&1
Примерно так: Это выведет все stderr и stdout в $ LOGFILE.
Теперь, так как вы хотите, чтобы это отображалось на консоли, а также в лог-файле, вам также придется использовать именованный канал для exec для записи и tee для чтения.
(Однострочник Денниса технически тоже делает это, хотя, очевидно, по-другому). Сама труба создается с помощью mkfifo $PIPEFILE
. Затем сделайте следующее.
# Начните писать в файл журнала, но извлеките его из нашего именованного канала.
тройник $ LOGFILE <$ PIPEFILE &
# захватить идентификатор процесса тройника для команды ожидания.
TEEPID = $!
# перенаправить оставшуюся часть stderr и stdout в наш именованный канал.
exec> $ PIPEFILE 2> & 1
echo "Сделай свои команды здесь"
echo "Все их стандартные выходы получат teed."
echo "Так будет и их стандартная ошибка"> & 2
# закройте дескрипторы файлов stderr и stdout.
exec 1> & - 2> & -
# Дождитесь окончания тройника, так как теперь другой конец трубы закрыт.
подождите $ TEEPID
Если вы хотите быть тщательным, вы можете создать и уничтожить файл именованного канала в начале и конце вашего скрипта.
Для справки, я почерпнул большую часть этого из очень информативного поста в блоге случайного парня: ( Архивная версия )