问题描述
我有一个简单的脚本:
#!/bin/bash
set -e
trap "echo BOO!" ERR
function func(){
ls /root/
}
func
如果我的脚本失败,我想捕获ERR(因为在这里b/c,我没有权限查看/root).但是,使用 set -e
时不会被捕获.没有 set -e
的情况下,会捕获ERR.
I would like to trap ERR if my script fails (as it will here b/c I do not have the permissions to look into /root). However, when using set -e
it is not trapped. Without set -e
ERR is trapped.
根据bash手册页,对于 set -e
:
According to the bash man page, for set -e
:
为什么我的陷阱没有被执行?从手册页看来应该如此.
Why isn't my trap executed? From the man page it seems like it should.
推荐答案
chepner的答案是最好的解决方案:如果要组合 set -e
(与 set -o errexit
相同)和 ERR
陷阱,也请使用 set -o errtrace
(与以下代码相同: set -E
).
chepner's answer is the best solution: If you want to combine set -e
(same as: set -o errexit
) with an ERR
trap, also use set -o errtrace
(same as: set -E
).
简而言之:使用 set -eE
代替 set -e
:
#!/bin/bash
set -eE # same as: `set -o errexit -o errtrace`
trap 'echo BOO!' ERR
function func(){
ls /root/
}
# Thanks to -E / -o errtrace, this still triggers the trap,
# even though the failure occurs *inside the function*.
func
man bash
说到有关 set -o errtrace
/ set -E
:
我相信正在发生的事情:
What I believe is happening:
-
无
-e
:ls
命令在函数内部失败,并且由于是函数中的最后一条命令,该函数将ls
的非零退出代码报告给您的顶级脚本范围调用者.在那个范围中,ERR
陷阱有效并被调用(但请注意,执行将继续,除非您从以下位置显式调用exit
陷阱).
Without
-e
: Thels
command fails inside your function, and, due to being the last command in the function, the function reportsls
's nonzero exit code to the caller, your top-level script scope. In that scope, theERR
trap is in effect, and it is invoked (but note that execution will continue, unless you explicitly callexit
from the trap).
使用 -e
(但不使用 -E
): ls
命令失败在您的函数内部,并且由于 set -e
生效,Bash 立即退出,直接从函数作用域-和由于没有有效的那里陷阱(因为它不是从父作用域继承的),因此不会调用陷阱.
With -e
(but without -E
): The ls
command fails inside your function, and because set -e
is in effect, Bash instantly exits, directly from the function scope - and since there is no ERR
trap in effect there (because it wasn't inherited from the parent scope), your trap is not called.
尽管 man
页面不正确,但我同意这种行为并不十分明显-您必须进行推断.
While the man
page is not incorrect, I agree that this behavior is not exactly obvious - you have to infer it.
这篇关于在Bash中使用'set -e'时如何捕获ERR的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!