本文介绍了在Bash中使用'set -e'时如何捕获ERR的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的脚本:

#!/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: The ls command fails inside your function, and, due to being the last command in the function, the function reports ls's nonzero exit code to the caller, your top-level script scope. In that scope, the ERR trap is in effect, and it is invoked (but note that execution will continue, unless you explicitly call exit 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 07:39