普通shell vs subshel​​l vs“bash -c”最后一个命令退出代码

我试图获得与&&和||链接的最后一个命令的退出代码 正确。

我遇到了一个我无法解释的奇怪的行为。 请帮忙。

我使用这个testing脚本来返回给定的退出代码:

gdubicki@mbp-greg:~ $ cat exit-code.sh #!/bin/bash echo "running exit-code with $1" exit $1 

这按预期工作:

 gdubicki@mbp-greg:~ $ ./exit-code.sh 1 && ./exit-code.sh 2 && ./exit-code.sh 3 || echo last exit code: $? running exit-code with 1 last command exit code: 1 gdubicki@mbp-greg:~ $ (./exit-code.sh 1 && ./exit-code.sh 2 && ./exit-code.sh 3 || echo last exit code: $?) running exit-code with 1 last exit code: 1 

但:

 gdubicki@mbp-greg:~ $ /bin/bash -c "./exit-code.sh 1 && ./exit-code.sh 2 && ./exit-code.sh 3 || echo last exit code: $?" running exit-code with 1 last exit code: 0 

为什么我在这里得到退出码0?

为什么我在这里得到退出码0?

原因是用双引号引起的参数扩展(特殊参数$? )是在将parameter passing给新的Bash进程之前进行的。 如果打开debugging和详细模式,可以清楚地看到:

 $ set -xv $ bash -c "(./exit-code.sh 1 && ./exit-code.sh 2 && ./exit-code.sh 3 || echo last exit code: $?)" bash -c "(./exit-code.sh 1 && ./exit-code.sh 2 && ./exit-code.sh 3 || echo last exit code: $?)" + bash -c '(./exit-code.sh 1 && ./exit-code.sh 2 && ./exit-code.sh 3 || echo last exit code: 0)' running exit-code with 1 last exit code: 0 $ set +xv 

在这种情况下$? 设置为0因为前面的命令(本例中set -xv )成功执行。

行情

只用单引号

 /bin/bash -c './exit-code.sh 1 && ./exit-code.sh 2 && ./exit-code.sh 3 || echo last exit code: $?' running exit-code with 1 last exit code: 1