bash: set -o errexit 在命令发生错误时不会退出。你怎样修改代码使其在发生错误时退出?

14 浏览
0 Comments

bash: set -o errexit 在命令发生错误时不会退出。你怎样修改代码使其在发生错误时退出?

在bash的man页面中,它指出:

如果一个流水线(可以由一个简单的命令组成)、一个被括号括起来的子shell命令,或者一个被花括号括起来的命令列表中的命令...

所以我认为函数应该被视为被花括号括起来的命令列表。然而,如果你对函数调用应用条件语句,errexit就不再在函数体内持续存在,而是在返回之前执行整个命令列表。即使你在函数内部显式地创建了一个启用errexit的子shell,所有命令列表中的命令也会被执行。下面是一个简单的示例,演示了这个问题:

function a() { b ; c ; d ; e ; }
function ap() { { b ; c ; d ; e ; } ; }
function as() { ( set -e ; b ; c ; d ; e ) ; }
function b() { false ; }
function c() { false ; }
function d() { false ; }
function e() { false ; }


( set -Eex ; a )
+ a
+ b
+ false


( set -Eex ; ap )
+ ap
+ b
+ false


( set -Eex ; as )
+ as
+ set -e
+ b
+ false

现在如果我对它们应用条件语句...

( set -Eex ; a || false )
+ a
+ b
+ false
+ c
+ false
+ d
+ false
+ e
+ false
+ false


( set -Eex ; ap || false )
+ ap
+ b
+ false
+ c
+ false
+ d
+ false
+ e
+ false
+ false


( set -Eex ; as )
+ as
+ set -e
+ b
+ false
+ c
+ false
+ d
+ false
+ e
+ false
+ false

0
0 Comments

问题:

在bash中,当命令发生错误时,set -o errexit并没有退出。如何更改代码以使其在发生错误时退出?

原因:

这个问题的原因是,set -o errexit命令并不会在发生错误时立即退出。根据bash手册和POSIX的规定,这是bash的预期行为。因此,我们需要采取其他方法来实现在发生错误时退出的功能。

解决方法:

我们可以通过在脚本中设置陷阱(trap)来实现在发生错误时退出的功能。下面是一个示例代码:

function on_error() {
    echo "error happened!"
}
trap on_error ERR
echo "OK so far"
false
echo "this line should not execute"

在上面的代码中,我们定义了一个名为on_error的函数,当发生错误时会调用这个函数。然后,我们使用`trap on_error ERR`将这个函数与ERR陷阱关联起来。这样,当脚本中的命令发生错误时,on_error函数会被调用。

在这个例子中,我们首先输出了"OK so far",然后使用`false`命令故意制造了一个错误。由于设置了ERR陷阱,当错误发生时,会调用on_error函数并输出"error happened!"。然后,脚本会立即退出,因此后面的"this line should not execute"不会被执行。

需要注意的是,为了使ERR陷阱生效,我们还需要在脚本的开始处添加`set -e`命令,以确保脚本在发生错误时立即退出。

总结起来,通过设置陷阱函数和使用`set -e`命令,我们可以实现在bash中在发生错误时退出的功能。

0