我正在使用 ERR 陷阱来捕获我的 bash 脚本中的任何错误并输出发生的日志。(类似于这个问题:Trap, ERR, and echoing the error line)它按预期工作。唯一的问题是,在我的脚本中的某个时刻,exitcode !=0 预计会发生。在这种情况下如何使陷阱不触发?
这是一些代码:
err_report() {
echo "errexit on line $(caller)" | tee -a $LOGFILE 1>&2
}
trap err_report ERR
然后在脚本的后面:
<some command which occasionally will return a non-zero exit code>
if [ $? -eq 0 ]; then
<handle stuff>
fi
每次命令返回非零时,都会触发我的陷阱。我可以只为这部分代码避免这种情况吗?
我检查了这个问题:使用 `set -eu` 时 EXIT 和 ERR 陷阱的正确行为, 但我并没有真正了解如何将它应用于我的案例 - 如果完全适用的话。
如果
ERR
trap
立即“捕获”错误代码,则不会触发,这意味着您可以使用if
语句和诸如此类的东西,而不必一直打开和关闭错误捕获。但是,您不能将检查$?
用于流量控制,因为当您进行该检查时,您已经(可能)有未捕获的错误。如果您有一个预期会失败的命令——并且您不希望这些失败触发
trap
,您只需捕获失败。将它们包装在一个if
语句中既笨重又冗长,但是这个速记很好用:但是,如果你想在命令失败时做一些事情,在
if
这里会很好:或者,
else
也将捕获错误状态:总而言之,
set -e
只有trap "command" ERR
在存在没有立即和本质上考虑的错误情况时才会跳闸。ERR
陷阱遵循与 相同的规则,set -e
即它不会对用作条件的命令生效。所以,请记住,
if
条件中的命令可以是任何命令,不一定是[ .. ]
. 因此,如果您只想对命令的退出状态进行真/假评估,只需在if
条件中直接使用它即可。如果您需要保存退出代码并避免
ERR
陷阱,您需要执行类似的操作在这里,
&&
将挤压ERR
陷阱,但由于它仅在退出代码为零时运行,所以我们将知道退出代码在:
.您可能想查看BashFAQ 105:为什么 set -e (或 set -o errexit,或陷阱 ERR) 没有达到我的预期?
ERR
您可以根据需要在部分代码期间启用/禁用陷阱。