忽略Bash pipefail错误代码141

Ale*_*lds 10 python error-handling bash signals sigpipe

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

但是,我们SIGPIPE遇到了错误(错误代码141),其中数据被写入不再存在的管道.

有没有办法设置bash来忽略SIGPIPE错误,或者是否有一种方法来编写一个错误处理程序来处理所有错误状态代码,比如0和141?

例如,在Python中,我们可以添加:

signal.signal(signal.SIGPIPE, signal.SIG_DFL) 
Run Code Online (Sandbox Code Playgroud)

将默认行为应用于SIGPIPE错误:忽略它们(参见http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-06/3823.html).

bash中是否有类似的选项?

che*_*ner 9

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

trap '' PIPE
Run Code Online (Sandbox Code Playgroud)

  • 似乎有两个相反的问题(“有没有办法将 bash 设置为忽略 SIGPIPE 错误”,我回答了这个问题,“[我] 有一种方法可以编写处理所有错误状态代码的错误处理程序,但是,说, 0 和 141”,我将其解释为“处理所有内容 * 除了 * SIGPIPE”。) (2认同)

Doc*_*r J 7

我通过处理一个|| if ...语句来吞下退出代码141,但仍然冒出任何其他错误,从而在每个管道的基础上处理这个问题:

pipe | that | fails || if [[ $? -eq 141 ]]; then true; else exit $?; fi
Run Code Online (Sandbox Code Playgroud)

  • 假设也使用`set -e`(`set -o errexit`),这可以缩短为`pipe | 那个| 失败|| 测试$?-eq 141`(当然,还有一些不可或缺的评论,解释了幻数). (3认同)
  • 请注意,这不会保留管道的原始退出代码。尽管看起来如此,但由于“[[”执行了测试命令,“else exit $?”将返回 1。[此处显示](/sf/answers/5109000921/) 是保留退出代码的替代解决方案。 (3认同)

Jac*_*nor 5

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

但是您可以在每个命令的基础上执行此操作。该||运营商抑制由第一命令返回的任何错误,所以你可以这样做:

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