我正在尝试将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中,显示消息“检测到非零退出代码!”不见了。知道为什么吗? 谢谢!
答案 0 :(得分:4)
ERR
陷阱触发“简单命令”管道不是一个简单的命令。
它可能会触发整个管道的结果(我不确定),你可以通过设置pipefail
来获得更接近你想要的东西。
(注意:这是人们通常不建议使用set -e
的原因之一,因为它有这样令人惊讶的细节。)
pipefail
工作的原因是通常管道的返回状态是最后一个命令的返回,但是pipefail
上的命令变为最后一个命令失败的返回状态。
管道的返回状态是最后一个命令的退出状态, 除非启用了pipefail选项。如果启用了pipefail,则 管道的返回状态是最后(最右边)命令的值 以非零状态退出,如果所有命令退出成功则返回零 - 充分。