我正在尝试执行以下代码:
set -euxo pipefail
yes phrase | make installer
Run Code Online (Sandbox Code Playgroud)
在哪里Makefile使用phrasefrom stdin 创建安装程序文件。但是,此命令以错误代码 141 结尾,这会破坏我的 CI 构建。这个例子可以简化为:
yes | tee >(echo yo)
Run Code Online (Sandbox Code Playgroud)
从这里看到的内容:管道故障 (141) 当管道输出到三通时——为什么?- 这个错误意味着管道消费者刚刚停止消费输出 - 这在我的情况下非常好。
有没有办法抑制管道错误,然后从make installer?
141 退出代码表示进程失败,并显示SIGPIPE; 这发生yes在管道关闭时。要为您的 CI 掩盖这一点,您需要使用类似的东西来掩盖错误
(yes phrase ||:) | make installer
Run Code Online (Sandbox Code Playgroud)
这将运行yes phrase,如果失败,运行:以代码 0 退出。这足够安全,因为yes除了无法写入之外没有太多原因导致失败。
要调试此类管道问题,最好的方法是查看PIPESTATUS:
yes phrase | make installer || echo ${PIPESTATUS[@]}
Run Code Online (Sandbox Code Playgroud)
这将显示失败时管道所有部分的退出代码。然后可以适当处理那些因退出代码 141 而失败的问题。特定错误代码的通用处理模式是
(command; ec=$?; if [ "$ec" -eq 141 ]; then exit 0; else exit "$ec"; fi)
Run Code Online (Sandbox Code Playgroud)
(感谢Hauke Laging);这会运行command,如果command成功则以代码 0 退出,或者以代码 141 退出。其他退出代码按原样反映。