2014-12-18 3 views
4

Я пытаюсь зарегистрировать все, что выходит из 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 отображается сообщение «Без кода нулевого выхода!» пропал, отсутствует. Любая идея почему? Спасибо!

+1

ERR-ловушка для «простых команд» - это не простая команда. Он может срабатывать для результата всего конвейера (я не уверен), и вы можете получить что-то поближе к тому, что хотите, установив 'pipefail'. Это одна из причин, почему люди часто не рекомендуют использовать 'set -e', поскольку у этого есть удивительные детали, подобные этому. –

+0

Спасибо! Я добавил 'set -o pipefail', и он сработал. Однако я не совсем понял, почему 'set -e' не рекомендуется. Есть ли у него другие оговорки? Также, пожалуйста, добавьте ответ, чтобы принять его. – cristiprg

+0

'set -e' имеет аналогичные оговорки в ловушке' ERR'. Он не срабатывает во всех ситуациях, которые вы могли бы ожидать. И некоторые из этих ситуаций являются внешними по отношению к вашему другому рабочему коду. –

ответ

3

ERR ловушки для «простых команд» - это не простая команда.

Он может выстрелить из результата всего трубопровода (я не уверен), и вы можете получить что-то ближе к тому, что хотите, установив pipefail.

(Примечание: Это одна из причин, почему люди часто не рекомендуют использовать set -e как это имеет удивительные детали, как это.)

Причиной, побуждающей pipefail работы является то, что обычно возвращается статус трубопровода является возвращение последней команды, но с pipefail на нем становится статусом возврата последней команды, которая терпит неудачу.

Состояние возврата конвейера - это статус выхода последней команды, , если опция pipefail не включена. Если pipefail включен, статус возврата - это значение последней (самой правой) команды для выхода с ненулевым статусом или нуля, если все команды успешно завершены - .

+0

Спасибо, ясное объяснение! – cristiprg

Смежные вопросы