为什么 `source foo && true` 在 bash 中退出脚本?

vca*_*llo 1 shell bash shell-script

所以,我读过这个: 带有 `set -e` 的 Bash 脚本不会在 `... && ...` 命令上停止

这说得通。那么现在问题来了:

测试A:

$ cat ./test.sh 

set -ex
source foo && true
echo 'running'

$ ./test.sh 
++ source foo
./test.sh: line 16: foo: No such file or directory

$ echo $?
1
Run Code Online (Sandbox Code Playgroud)

测试乙:

$ cat ./test.sh 

set -ex
cat foo && true
echo 'running'

$ ./test.sh 
++ cat foo
cat: foo: No such file or directory
++ echo running
running

$ echo $?
0
Run Code Online (Sandbox Code Playgroud)

为什么source唯一违反此规则(粗体)?

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

sch*_*ily 5

source是 dot.命令的别名,并且 dot 命令是所谓的special command,其中 POSIX 描述这些命令在发生错误时退出整个非交互式 shell。

如果您通过以下方式调用命令:

bash test.sh
Run Code Online (Sandbox Code Playgroud)

bash 不会退出,但是当您调用时:

bash -o posix test.sh
Run Code Online (Sandbox Code Playgroud)

它退出。因此,要么您的 bash 默认已编译为符合 POSIX 标准,要么您确实调用了与 bash 不同的 shell。

有关标准,请参阅http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_14

  • Bash 在使用名为 sh 的文件调用时进入 posix 模式。这是第三种可能性,也是适用于 IMO 的可能性(未编译,也未编译其他 shell)。 (2认同)