Bash: ловушка ERR не работает, когда используется оператор трубы

Я пытаюсь записать все, что выходит из stdout и stderr, в файл журнала и все еще сохранить консоль. Для этого я просто добавил: |& tee -a log_file.log к каждой команде.
Тем не менее, я также хочу запустить пользовательскую команду, если во время сценария произошла какая-либо ошибка. Для этого я добавил следующее в начале скрипта: trap "echo Non-zero exit code detected" ERR.
Проблема в том, что при использовании оператора pipe эхо в ловушке больше не выполняется.

Сценарий 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 

Выход 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 появляется сообщение «Обнаружен ненулевой код выхода!» пропал, отсутствует. Есть идеи почему? Спасибо!

4 голоса | спросил cristiprg 18 ThuEurope/Moscow2014-12-18T15:39:51+03:00Europe/Moscow12bEurope/MoscowThu, 18 Dec 2014 15:39:51 +0300 2014, 15:39:51

1 ответ


0

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

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

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

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

  

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

ответил Etan Reisner 18 ThuEurope/Moscow2014-12-18T16:01:12+03:00Europe/Moscow12bEurope/MoscowThu, 18 Dec 2014 16:01:12 +0300 2014, 16:01:12

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132