Bash:使用管道运算符时,陷阱ERR不起作用

时间:2014-12-18 12:39:52

标签: linux bash pipe tee bash-trap

我正在尝试将stdout和stderr中的所有内容记录到日志文件中,并仍保留控制台。为此,我只是将|& tee -a log_file.log添加到每个命令中 但是,如果脚本期间发生任何错误,我还想运行自定义命令。为此,我在脚本的开头添加了以下内容:trap "echo Non-zero exit code detected" ERR 问题是使用管道操作符,陷阱中的回显不再执行。

脚本1,没有管道:

$cat test.sh
#!/bin/bash

trap "echo Non-zero exit code detected!" ERR

function fail_please()
{
    echo "Returning non-zero exit code!"
    return 1
}

fail_please 

输出1:

$ ./test.sh 
Returning non-zero exit code!
Non-zero exit code detected!

脚本2,带管道:

$ cat test.sh
#!/bin/bash

trap "echo Non-zero exit code detected!" ERR

function fail_please()
{
    echo "Returning non-zero exit code!"
    return 1
}

fail_please |& tee log_file.log 

输出2:

$ ./test.sh
Returning non-zero exit code!
$ cat log_file.log 
Returning non-zero exit code!

在输出2中,显示消息“检测到非零退出代码!”不见了。知道为什么吗? 谢谢!

1 个答案:

答案 0 :(得分:4)

ERR陷阱触发“简单命令”管道不是一个简单的命令。

它可能会触发整个管道的结果(我不确定),你可以通过设置pipefail来获得更接近你想要的东西。

(注意:这是人们通常不建议使用set -e的原因之一,因为它有这样令人惊讶的细节。)

pipefail工作的原因是通常管道的返回状态是最后一个命令的返回,但是pipefail上的命令变为最后一个命令失败的返回状态。

  

管道的返回状态是最后一个命令的退出状态,   除非启用了pipefail选项。如果启用了pipefail,则   管道的返回状态是最后(最右边)命令的值   以非零状态退出,如果所有命令退出成功则返回零 -   充分。