bash -e 和 && 函数内部的评估

ZiG*_*iGi 2 shell bash dash shell-script

-e设置选项时,我对 bash(和破折号)行为感到困惑。

简单的例子:

#!/bin/bash -e

func() {
    false && true
}

false && true

echo "1"

func

echo "2"
Run Code Online (Sandbox Code Playgroud)

输出:

1
Run Code Online (Sandbox Code Playgroud)

预期输出:

1
2
Run Code Online (Sandbox Code Playgroud)

虽然第一次出现按预期工作,但第二次出现(在函数内部)会导致立即退出。我搜索了文档,但无法找到对这种不同行为的解释。这背后有什么理由吗,还是这个错误?我在 bash 和 dash 中对此进行了测试,结果相同。

根据 bash 联机帮助页:

-e 如果管道(可能由单个简单命令组成)、列表或复合命令(参见上面的 SHELL GRAMMAR)以非零状态退出,则立即退出。如果失败的命令是紧跟在所述命令列表的一部分的壳不退出 whileuntil关键字,继该测试的一部分ifelif保留字,在执行任何命令的一部分&&||除命令列表以下的最终&&||,任何管道中的命令但最后一个,或者如果命令的返回值被!. 如果除子 shell 之外的复合命令由于命令在-e被忽略时失败而返回非零状态,则 shell 不会退出。一个陷阱ERR,如果设置,在 shell 退出之前执行。此选项分别适用于 shell 环境和每个子 shell 环境(参见上面的命令执行环境),并且可能导致子 shell 在执行子 shell 中的所有命令之前退出。

如果复合命令或 shell 函数在-e被忽略的上下文中执行,则在复合命令或函数体内执行的任何命令都不会受到-e设置的影响,即使-e设置了并且命令返回失败状态也是如此。如果复合命令或 shell 函数-e-e被忽略的上下文中执行时设置,则在复合命令或包含函数调用的命令完成之前,该设置不会产生任何影响。

Kus*_*nda 5

脚本在从 返回时终止func,因为它的退出状态非零。脚本不会在func.

false && true列表不受 的影响-e,并且脚本不会由此终止,不在脚本的主要部分,也不在函数中。

但是,false函数中的 将函数的退出状态设置为非零,因此当函数返回时,shell 终止。

您的脚本可能会简化为

#!/bin/bash -e

false && true

echo "1"

false

echo "2"
Run Code Online (Sandbox Code Playgroud)

您可能还想测试从您的函数返回零以说服自己函数中的false && true列表不会终止脚本:

#!/bin/bash -e

func() {
    false && true
    return 0
}

false && true

echo "1"

func

echo "2"
Run Code Online (Sandbox Code Playgroud)

运行此输出

1
2
Run Code Online (Sandbox Code Playgroud)