Что касается решения для перенаправления большого количества команд одновременно:
#!/bin/bash
{
somecommand
somecommand2
somecommand3
} 2>&1 | tee -a $DEBUGLOG
Почему ваше оригинальное решение не работает: exec 2> & 1 перенаправит стандартный вывод ошибок на стандартный вывод вашей оболочки, который, если вы запустите скрипт из консоли, станет вашей консолью. перенаправление канала на команды будет перенаправлять только стандартный вывод команды.
С точки зрения somecommand
, его стандартный вывод идет в канал, связанный с, tee
и стандартная ошибка идет в тот же файл / псевдофайл, что и стандартная ошибка оболочки, которую вы перенаправляете на стандартный вывод оболочки, который будет консоль, если вы запускаете свою программу из консоли.
Единственный верный способ объяснить это - посмотреть, что на самом деле происходит:
Исходная среда вашей оболочки может выглядеть так, если вы запустите ее из терминала:
stdin -> /dev/pts/42
stdout -> /dev/pts/42
stderr -> /dev/pts/42
После того, как вы перенаправили стандартную ошибку в стандартный вывод ( exec 2>&1
), вы ... ничего не меняете. Но если вы перенаправите стандартный вывод скрипта в файл, вы получите такую среду:
stdin -> /dev/pts/42
stdout -> /your/file
stderr -> /dev/pts/42
Тогда перенаправление стандартной ошибки оболочки в стандартный вывод закончится так:
stdin -> /dev/pts/42
stdout -> /your/file
stderr -> /your/file
Выполнение команды унаследует эту среду. Если вы запустите команду и передадите ее по каналу, среда команды будет такой:
stdin -> /dev/pts/42
stdout -> pipe:[4242]
stderr -> /your/file
Таким образом, стандартная ошибка вашей команды все еще входит в то, что оболочка использует в качестве стандартной ошибки.
Вы можете фактически увидеть среду команды, посмотрев в /proc/[pid]/fd
: используйте, ls -l
чтобы также перечислить содержимое символической ссылки. 0
Файл здесь стандартный ввод, 1
стандартный выход и 2
стандартная ошибка. Если команда открывает больше файлов (и большинство программ открывают), вы также увидите их. Программа также может выбрать перенаправление или закрытие стандартного ввода / вывода и повторное использование 0
, 1
и 2
.
|&
работает как ярлык2>&1 |
, хотя бы немного удобнее.