如何防止一个命令触发 ERR 陷阱?

mas*_*sgo 2 bash trap

我正在使用 ERR 陷阱来捕获 bash 脚本中的任何错误并输出日志中发生的事情。(类似于这个问题:Trap, ERR, and echoing the error line)它按预期工作。唯一的问题是,在我的脚本中的某个时刻,预期会发生退出代码 !=0。在这种情况下如何使陷阱不触发?

这是一些代码:

err_report() {
    echo "errexit on line $(caller)" | tee -a $LOGFILE 1>&2
}

trap err_report ERR
Run Code Online (Sandbox Code Playgroud)

然后在脚本中:

<some command which occasionally will return a non-zero exit code>

if [ $? -eq 0 ]; then
    <handle stuff>
fi
Run Code Online (Sandbox Code Playgroud)

每次命令返回非零值时,都会触发我的陷阱。我可以只针对这部分代码避免这种情况吗?

我检查了这个问题:使用`set -eu` 时 EXIT 和 ERR 陷阱的正确行为, 但我真的不知道如何将它应用于我的案例 - 如果完全适用的话。

Dop*_*oti 5

一个ERR trap不会触发如果错误代码立即“捕获”,这意味着你可以使用if语句和诸如此类的东西,而无需翻转错误捕获和关闭所有的时间。但是,您不能使用$?流量控制检查,因为在进行该检查时,您已经(可能)遇到了未捕获的错误。

如果您有一个希望失败的命令——并且您希望这些失败触发trap,那么您只需捕获失败。将它们包装在一个if语句中既笨拙又冗长,但这个速记很有效:

/bin/false || :  # will not trigger an ERR trap
Run Code Online (Sandbox Code Playgroud)

但是,如果你想在命令失败时做一些事情,if在这里就可以了:

if ! /bin/false; then
    echo "this was not caught by the trap!"
fi
Run Code Online (Sandbox Code Playgroud)

或者,else也将捕获错误状态:

if /bin/false; then
    : # dead code
else
    echo "this was not caught by the trap!"
fi
Run Code Online (Sandbox Code Playgroud)

总之,set -e并且trap "command" ERR只得到如果它不是立即本质上占一个错误条件跳闸。

  • 就像一个命令:`if ! 富 | 酒吧| 巴兹 | 库克斯;然后东西;fi`。 (2认同)