重击:使用管道运算符时,陷阱ERR不起作用 [英] Bash: Trap ERR does not work when pipe operator is used

查看:105
本文介绍了重击:使用管道运算符时,陷阱ERR不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将来自stdout和stderr的所有内容记录到日志文件中,并且仍然保留控制台.为此,我仅在每个命令后附加:|& tee -a log_file.log.
但是,如果脚本执行过程中发生任何错误,我也想运行自定义命令.为此,我在脚本的开头添加了以下内容:trap "echo Non-zero exit code detected" ERR.
问题是通过使用管道运算符,陷阱中的回声不再执行.

I am trying to log everything that comes out of stdout and stderr into a log file and still preserve the console. For this, I just appended: |& tee -a log_file.log to every command.
However, I also want to run a custom command if any error occurred during the script. For this, I added the following at the beginning of the script: trap "echo Non-zero exit code detected" ERR.
The problem is by using the pipe operator, the echo in the trap does not execute anymore.

脚本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中,消息检测到非零退出代码!"不见了.知道为什么吗? 谢谢!

In output 2, the message "Non-zero exit code detected!" is missing. Any idea why? Thanks!

推荐答案

ERR陷阱针对简单命令"触发,管道不是简单命令.

The ERR trap fires for "simple commands" a pipeline is not a simple command.

这可能会激发整个流水线的结果(我不确定),并且通过设置pipefail您可能能够更接近所需的内容.

It might fire for the result of the whole pipeline (I'm not sure) and you might be able to get something closer to what you want by setting pipefail.

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

(Note: This is one of the reasons people often don't recommend using set -e as it has surprising details like this.)

pipefail起作用的原因是,正常情况下,管道的返回状态是最后一条命令的返回,但是带有pipefail的管道将成为失败的最后一条命令的返回状态.

The reason pipefail works is that normally the return status of a pipeline is the return of the last command but with pipefail on it becomes the return status of the last command that fails.

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

The return status of a pipeline is the exit status of the last command, unless the pipefail option is enabled. If pipefail is enabled, the pipeline’s return status is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands exit success- fully.

这篇关于重击:使用管道运算符时,陷阱ERR不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆