假设我们有一个这样的脚本。
#!/bin/bash
set -e
ls notexist && ls notexist
echo still here
不会因为 set -e 而退出
但
#!/bin/bash
set -e
ls notexist || ls notexist
echo still here
将要。为什么?
bash手册说set -e
:
The shell does not exit if the command that fails is [...]
part of any command executed in a && or || list except the
command following the final && or ||
破折号手册说:
If not interactive, exit immediately if any untested command fails.
The exit status of a command is considered to be explicitly tested
if the command is used to control an if, elif, while, or until;
or if the command is the left hand operand of an “&&” or “||” operator.
对于AND测试,shell 将在“左手操作数”测试期间提前停止。因为还有测试,它会认为整个命令是“测试的”,因此不会中止。
对于OR测试,shell 必须运行所有(两个)测试,并且一旦最后一个测试失败,它会断定存在未经检查的错误并因此中止。
我同意这有点违反直觉。
因为正如 Bash 手册所说set -e
:
如果失败的命令是紧跟在 while 或 until 关键字之后的命令列表的一部分、位于 if 或 elif 保留字之后的测试的一部分、在 && 或 || 中执行的任何命令的一部分,则 shell 不会退出 列出除了最后一个 && 或 || 之后的命令,管道中除最后一个以外的任何命令,或者命令的返回值是否用 ! 反转。
该ls notexist || ls notexist
命令终止 shell,因为第二个(最后一个)ls notexist
未成功退出。ls notexist && ls notexist
不会终止 shell,因为“&& list”的执行在第一次失败后停止,第二ls notexist
个(最后一个)永远不会到达。
顺便说一句,使用true
andfalse
而不是特定命令(例如ls notexist
.