bash: set -o errexit 在命令发生错误时不会退出。你怎样修改代码使其在发生错误时退出?
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
问题:
在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中在发生错误时退出的功能。