20

如果在管道的任何步骤中存在非零错误的情况下捕获到非零错误,则设置 bashpipefail选项(通过)允许脚本失败。set -o pipefail

但是,我们遇到了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 中是否有一些类似的选项?

4

3 回答 3

22

|| if ...我通过添加一个声明以吞下退出代码 141 但仍然冒泡任何其他错误,从而在每个管道的基础上处理此问题:

pipe | that | fails || if [[ $? -eq 141 ]]; then true; else exit $?; fi
于 2015-10-08T22:27:57.897 回答
10

trap命令允许您指定遇到信号时要运行的命令。要忽略信号,请传递空字符串:

trap '' PIPE
于 2014-03-17T20:43:13.167 回答
6

我知道没有一种方法可以为整个脚本执行此操作。一般来说,这是有风险的,因为没有办法知道子进程没有返回 141 出于不同的原因。

但是您可以在每个命令的基础上执行此操作。运算符会抑制第一个命令返回的||任何错误,因此您可以执行以下操作:

set -e -o pipefail
(cat /dev/urandom || true) | head -c 10 | base64
echo 'cat exited with SIGPIPE, but we still got here!'
于 2015-09-14T20:38:08.297 回答