忽略错误代码 141 的 Bash pipefail

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22464786/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 09:56:41  来源:igfitidea点击:

Ignoring Bash pipefail for error code 141

pythonbasherror-handlingsignalssigpipe

提问by Alex Reynolds

Setting the bash pipefailoption (via set -o pipefail) allows the script to fail if a non-zero error is caught where there is a non-zero error in any step of a pipe.

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

However, we are running into SIGPIPEerrors (error code 141), where data is written to a pipe that no longer exists.

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

Is there a way to set bash to ignore SIGPIPEerrors, or is there an approach to writing an error handler that will handle all error status codes but, say, 0 and 141?

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

For instance, in Python, we can add:

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

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

to apply the default behavior to SIGPIPEerrors: ignoring them (cf. http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-06/3823.html).

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

Is there some similar option available in bash?

bash 中是否有一些类似的选项可用?

采纳答案by chepner

The trapcommand lets you specify a command to run when encountering a signal. To ignore a signal, pass the empty string:

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

trap '' PIPE

回答by Doctor J

I handle this on a per-pipeline basis by tacking on an || if ...statement to swallow exit code 141 but still bubbling up any other errors:

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

pipe | that | fails || if [[ $? -eq 141 ]]; then true; else exit $?; fi

回答by Hyman O'Connor

There isn't a way that I know of to do this for the whole script. It would be risky in general, since there's no way to know that a child process didn't return 141 for a different reason.

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

But you can do this on a per-command basis. The ||operator suppresses any errors returned by the first command, so you can do something like:

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

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