Я пытаюсь зарегистрировать все, что выходит из stdout и stderr, в файл журнала и по-прежнему сохранять консоль. Для этого я просто добавил: |& tee -a log_file.log
к каждой команде.
Однако я также хочу запустить пользовательскую команду, если во время сценария произошла ошибка. Для этого я добавил следующее в начале скрипта: trap "echo Non-zero exit code detected" ERR
.
Проблема заключается в использовании оператора трубы, эхо в ловушке больше не выполняется.Bash: Trap ERR не работает, когда используется оператор трубы
Сценарий 1, без трубы:
$cat test.sh
#!/bin/bash
trap "echo Non-zero exit code detected!" ERR
function fail_please()
{
echo "Returning non-zero exit code!"
return 1
}
fail_please
Output 1:
$ ./test.sh
Returning non-zero exit code!
Non-zero exit code detected!
Сценарий 2, с трубой:
$ cat test.sh
#!/bin/bash
trap "echo Non-zero exit code detected!" ERR
function fail_please()
{
echo "Returning non-zero exit code!"
return 1
}
fail_please |& tee log_file.log
Выход 2:
$ ./test.sh
Returning non-zero exit code!
$ cat log_file.log
Returning non-zero exit code!
На выходе 2 отображается сообщение «Без кода нулевого выхода!» пропал, отсутствует. Любая идея почему? Спасибо!
ERR-ловушка для «простых команд» - это не простая команда. Он может срабатывать для результата всего конвейера (я не уверен), и вы можете получить что-то поближе к тому, что хотите, установив 'pipefail'. Это одна из причин, почему люди часто не рекомендуют использовать 'set -e', поскольку у этого есть удивительные детали, подобные этому. –
Спасибо! Я добавил 'set -o pipefail', и он сработал. Однако я не совсем понял, почему 'set -e' не рекомендуется. Есть ли у него другие оговорки? Также, пожалуйста, добавьте ответ, чтобы принять его. – cristiprg
'set -e' имеет аналогичные оговорки в ловушке' ERR'. Он не срабатывает во всех ситуациях, которые вы могли бы ожидать. И некоторые из этих ситуаций являются внешними по отношению к вашему другому рабочему коду. –