Linux Bash:Trap ERR在使用管道操作符时不起作用
我试图将stdout和stderr中的所有内容都记录到一个日志文件中,并且仍然保留控制台。为此,我只是在每个命令中添加了:Linux Bash:Trap ERR在使用管道操作符时不起作用,linux,bash,pipe,tee,bash-trap,Linux,Bash,Pipe,Tee,Bash Trap,我试图将stdout和stderr中的所有内容都记录到一个日志文件中,并且仍然保留控制台。为此,我只是在每个命令中添加了:|&tee-一个log\u文件.log。 但是,如果脚本执行过程中出现任何错误,我还希望运行自定义命令。为此,我在脚本开头添加了以下内容:trap“echo Non-zero exit code detected”ERR 问题是通过使用管道操作符,陷阱中的回声不再执行 脚本1,不带管道: $cat test.sh #!/bin/bash trap "echo Non-zer
|&tee-一个log\u文件.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中,缺少消息“检测到非零退出代码!”。知道为什么吗?
谢谢 为“简单命令”触发的陷阱管道不是简单命令 它可能会触发整个管道的结果(我不确定),通过设置
pipefail
,您可能可以获得更接近您想要的结果
(注意:这是人们不推荐使用set-e
的原因之一,因为它有这样令人惊讶的细节。)
pipefail
起作用的原因是管道的返回状态通常是最后一个命令的返回,但如果启用了pipefail
,它将成为最后一个失败命令的返回状态
管道的返回状态是最后一个命令的退出状态,
除非启用了pipefail选项。如果启用pipefail,则
管道的返回状态是最后一个(最右边)命令的值
以非零状态退出,如果所有命令退出成功,则为零-
完全
错误陷阱为“简单命令”触发管道不是简单命令。它可能会触发整个管道的结果(我不确定),通过设置
pipefail
,您可能可以获得更接近您想要的结果。这也是人们不推荐使用set-e
的原因之一,因为它有这样令人惊讶的细节。谢谢!我添加了set-o pipefail
,它成功了。然而,我不太明白为什么不建议使用set-e
。它还有其他警告吗?另外,请添加一个答案以接受它。set-e
对您的ERR
陷阱有类似的警告。它不会在所有你可能期望的情况下开火。其中一些情况是您的其他工作代码之外的。为了澄清这一点,在脚本2中,通过设置pipefail
,管道的返回代码仍然为0(因为tee返回0),但如果第一个命令失败,它将启用myERR
陷阱。这是正确的吗?我刚刚在回答中添加了一条注释,说明了为什么pipefail
有效,但是是的,它将返回到最后一个失败命令的退出状态,而不是始终是管道中最后一个命令的退出状态。