6

当我使用选项运行 bash 脚本时,我看到一些对我没有意义的行为,该-e选项具有多个与&&s 串在一起的命令并且其中一个失败。我希望脚本在失败的命令上停止并返回退出状态,但它只是愉快地执行脚本的其余部分。

以下是对我有意义的示例:

$ false && true; echo $?
1

$ bash -xe -c "false && true"; echo $?
+ false
1

$ bash -xe -c "false; true"; echo $?
+ false
1

这对我来说没有意义:

$ bash -xe -c "false && true; true"; echo $?
+ false
+ true
0

这是我不明白发生了什么的地方。false && true返回状态 1,所以脚本不应该停止执行并返回状态 1,就像脚本是时一样false; true

在试验过程中,我发现如果我用括号括住命令链,它的工作方式与我期望的一样:

$ bash -xe -c "(false && true); true"; echo $?
+ false
1

任何人都可以对此做出解释吗?

4

3 回答 3

8

这里的逻辑是您使用&&已经错误检查。同样,bash 不会将if条件内的失败视为值得中止,即使使用set -e.

当您将命令包装在括号中时,您实际上是在子 shell 中运行这些命令,因此脚本本身只看到该子 shell 的返回,即:它根本不知道&&所涉及的内容,因此它会按预期中止.

于 2013-02-12T17:12:40.047 回答
6

Quoth参考手册:

如果失败的命令是紧跟在 while 或 until 关键字之后的命令列表的一部分、if 语句中的测试的一部分、在 && 或 || 中执行的任何命令的一部分,则 shell 不会退出 列出除了最后一个 && 或 || 之后的命令,管道中除最后一个之外的任何命令,或者如果命令的返回状态正在与 !

于 2013-02-12T17:39:56.380 回答
1

为了避免在评估错误条件时退出 bash 脚本(具有set -e),使用 If-else 语句比短路更安全。

但是,如果您更喜欢较短的语法(就像我一样;-),请替换:

[[ 条件 ]] && 命令

和:

[[!条件]] || 命令

为了显示:

$ false && do_whatever ; echo rc=$?
rc=1 # i.e. Will exit bash at this point

$ ! false || do_whatever ; echo rc=$?
rc=0 # i.e. Bash will continue...
于 2020-03-23T11:46:58.923 回答