5

我正在尝试将来自 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 中,消息“检测到非零退出代码!” 不见了。知道为什么吗?谢谢!

4

1 回答 1

5

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

它可能会因为整个管道的结果而触发(我不确定),并且您可以通过设置pipefail.

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

起作用的原因pipefail是,通常管道的返回状态是最后一个命令的返回,但pipefail它成为最后一个失败命令的返回状态。

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

于 2014-12-18T13:01:12.373 回答