Игнорирование Bash pipefail для кода ошибки 141

6

Настройка параметра bash pipefail (через set -o pipefail) позволяет script сбой, если обнаружена ненулевая ошибка, где на любом этапе трубы есть ненулевая ошибка.

Однако мы сталкиваемся с ошибками SIGPIPE (код ошибки 141), где данные записываются в канал, который больше не существует.

Есть ли способ установить bash игнорировать ошибки SIGPIPE или есть подход к написанию обработчика ошибок, который будет обрабатывать все коды состояния ошибки, но, скажем, 0 и 141?

Например, в Python мы можем добавить:

signal.signal(signal.SIGPIPE, signal.SIG_DFL) 

применить поведение по умолчанию к ошибкам SIGPIPE: игнорировать их (см. http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-06/3823.html).

Есть ли аналогичная опция в bash?

Теги:
error-handling
signals
sigpipe

3 ответа

6
Лучший ответ

Команда trap позволяет указать команду для запуска, когда встречается сигнал. Чтобы игнорировать сигнал, пропустите пустую строку:

trap '' PIPE
  • 0
    Разве это не проигнорирует все ненулевые ошибки и победит pipefail ? Если это так, то как бы проверить код ошибки по сигналу, который был поднят, чтобы я мог continue на 0 и 141?
  • 0
    Это будет только игнорировать ошибки SIGPIPE , оставляя другие сигналы без изменений.
Показать ещё 2 комментария
4

Я обрабатываю это по каждому конвейеру, привязывая к оператору || if ... для проглатывания кода выхода 141, но все еще сталкиваясь с любыми другими ошибками:

pipe | that | fails || if [[ $? -eq 141 ]]; then true; else exit $?; fi
  • 2
    Предполагая, что set -e ( set -o errexit ) также используется, это можно сократить до pipe | that | fails || test $? -eq 141 (+ некоторые обязательные комментарии, конечно, объясняющие магическое число).
2

Я не знаю, как это сделать для всего script. Это было бы рискованно в целом, так как нет способа узнать, что детский процесс не возвратил 141 по другой причине.

Но вы можете сделать это на основе каждой команды. Оператор || подавляет любые ошибки, возвращенные первой командой, поэтому вы можете сделать что-то вроде:

set -e -o pipefail
(cat /dev/urandom || true) | head -c 10 | base64
echo 'cat exited with SIGPIPE, but we still got here!'

Ещё вопросы

Сообщество Overcoder
Наверх
Меню