У меня есть файл bash, который мне нужен, чтобы перенаправить весь вывод в один файл, журнал отладки, а также в терминал. Мне нужно перенаправить как stdout, так и stderr к отладке и зарегистрировать его для всех команд в сценарии.
Я не хочу добавлять 2>&1 | tee -a $DEBUG
для каждой команды в файле. Я мог бы жить с | tee -a $DEBUG
.
Я помню, что был способ сделать это с чем-то вроде exec 2>&1
.
В настоящее время я использую что-то вроде следующего:
#!/bin/bash
DEBUGLOG=/tmp/debug
exec 2>&1
somecommand | tee -a $DEBUGLOG
somecommand2 | tee -a $DEBUGLOG
somecommand3 | tee -a $DEBUGLOG
Но это не работает. У кого-нибудь есть решение / может объяснить причину?
|&
работает как ярлык2>&1 |
, хотя бы немного удобнее.Ответы:
Что касается решения для перенаправления большого количества команд одновременно:
Почему ваше оригинальное решение не работает: exec 2> & 1 перенаправит стандартный вывод ошибок на стандартный вывод вашей оболочки, который, если вы запустите скрипт из консоли, станет вашей консолью. перенаправление канала на команды будет перенаправлять только стандартный вывод команды.
С точки зрения
somecommand
, его стандартный вывод идет в канал, связанный с,tee
и стандартная ошибка идет в тот же файл / псевдофайл, что и стандартная ошибка оболочки, которую вы перенаправляете на стандартный вывод оболочки, который будет консоль, если вы запускаете свою программу из консоли.Единственный верный способ объяснить это - посмотреть, что на самом деле происходит:
Исходная среда вашей оболочки может выглядеть так, если вы запустите ее из терминала:
После того, как вы перенаправили стандартную ошибку в стандартный вывод (
exec 2>&1
), вы ... ничего не меняете. Но если вы перенаправите стандартный вывод скрипта в файл, вы получите такую среду:Тогда перенаправление стандартной ошибки оболочки в стандартный вывод закончится так:
Выполнение команды унаследует эту среду. Если вы запустите команду и передадите ее по каналу, среда команды будет такой:
Таким образом, стандартная ошибка вашей команды все еще входит в то, что оболочка использует в качестве стандартной ошибки.
Вы можете фактически увидеть среду команды, посмотрев в
/proc/[pid]/fd
: используйте,ls -l
чтобы также перечислить содержимое символической ссылки.0
Файл здесь стандартный ввод,1
стандартный выход и2
стандартная ошибка. Если команда открывает больше файлов (и большинство программ открывают), вы также увидите их. Программа также может выбрать перенаправление или закрытие стандартного ввода / вывода и повторное использование0
,1
и2
.источник
Вы можете использовать exec вот так вверху вашего скрипта:
Например:
Дает мне вывод в файл
$HOME/somefile.log
и на терминал, как это:источник
/bin/sh
сценариях (многие люди ошибочно используют синтаксис bash в/bin/sh
сценариях)./dev/fd/62: Operation not supported
какие-либо подсказки?myscript
и я запускаю./myscript > /dev/null
, я все равно должен увидеть,bye
откудаecho bye >&2
.Записать stderr и stdout в файл, отобразить stderr на экране (на stdout)
Полезно для крон, поэтому вы можете получать ошибки (и только ошибки) по почте
источник