我在 Bash 脚本中遇到了 set -e,但无法理解在 && 或 || 列表中最后一个 && 或 || 之后的命令评估会发生什么。我知道http://man7.org/linux/man-pages/man1/bash.1.html 对set -e 的以下引用:
如果失败的命令是 (...) 的一部分,shell 不会退出
在&& 或|| 列表中执行的任何命令,除了命令
在最后的&& 或|| 之后(...)
为了测试这个,我写了一个小的 Bash 脚本:
#!/bin/bash
bash -c "set -e ; true ; echo -n A"
bash -c "set -e ; false ; echo -n B"
bash -c "set -e ; true && true ; echo -n C"
bash -c "set -e ; true && false ; echo -n D"
bash -c "set -e ; false && true ; echo -n E"
bash -c "set -e ; false && false ; echo -n F"
bash -c "set -e ; true || true ; echo -n G"
bash -c "set -e ; true || false ; echo -n H"
bash -c "set -e ; false || true ; echo -n I"
bash -c "set -e ; false || false ; echo -n J"
echo ""
打印出来:
ACEFGHI
关于A:
true 没有非零状态。因此,shell 不会退出。
关于乙:
false 确实具有非零状态,并且不是&& 或|| 列表的一部分。因此,shell 退出。
关于C:
这是一个&& 或|| 列表。我们将不得不查看最后一个&& 或|| 之后的命令。该命令是true,它不具有非零状态。因此,是否对命令进行评估并不重要 - shell 不会以任何方式退出。
关于 D:
这是一个&& 或|| 列表。我们将不得不查看最后一个&& 或|| 之后的命令。这一次,命令是false,它确实具有非零状态。所以我们必须检查false 是否正在被评估——确实是这样,因为&& 正在关注true。因此,shell 退出。
关于E:
与 C 的推理相同:true 是最后一个 && 或 || 之后的命令。因此,shell 不会退出。
关于 F:
类似于D:这是一个&& 或|| 列表。我们将不得不查看最后一个&& 或|| 之后的命令。同样,命令是false,它确实具有非零状态。不过这次没关系,因为第一个命令也是false。由于它是 && 列表,因此不会评估第二个 false。因此,shell 不会退出。
关于 G:
与 C 或 E 的推理相同:true 是最后一个 && 或 || 之后的命令。因此,shell 不会退出。
关于 H:
这是一个&& 或|| 列表。我们将不得不查看最后一个&& 或|| 之后的命令。这个命令是false,它确实有一个非零状态,但它不会被评估,因为||前面是true。因此,shell 不会退出。
关于我:
与 C、E 或 G 的推理相同:true 是最后一个 && 或 || 之后的命令.因此,shell 不会退出。
关于 J:
这是&& 或|| 列表。我们将不得不查看最后一个&& 或|| 之后的命令。这个命令是false,它确实有一个非零状态。由于|| 前面是false,第二个false 将被评估。因此,shell 确实退出了。
您应该能够将这些测试用例应用于您的案例:true && false && true。由于最后一个&& 或|| 之后的命令是true,它不具有非零状态,因此&& 或|| 之前的命令无关紧要,shell 也不会退出方式。