#!/bin/bash -e
(false)
echo $?
echo "Line reached!"
以下是run:
时的输出[$]>Tests/Exec/continuous-integration.sh
1
Line reached!
Bash版本:CentOS上的3.2.25
答案 0 :(得分:10)
好像这与您的bash
版本有关。在我有权访问的计算机上,bash版本3.1.17和3.2.39表现出这种行为,bash 4.1.5没有。
虽然有点难看,但在两个版本中都有效的解决方案可能是这样的:
#!/bin/bash -e
(false) || exit $?
echo $?
echo "Line reached!"
bash源更改日志中有一些注释与set -e
选项的错误相关。
答案 1 :(得分:0)
我在El Capitan之前的SuSE 11.3和Mac OS上都看到了bash版本3.2.51中的这种行为。关于El Capitan的Bash 3.2.57有正确的#34;行为,即像bash 4。
但是,上面提出的解决方法,添加" ||退出$?"在子shell的关闭之后,无论什么版本的bash,都会击败-e标志的意图。来自man bash:
-e如果出现一个简单的命令(参见上面的SHELL GRAMMAR),则立即退出 具有非零状态。如果失败的命令是shell,则shell不会退出 部分命令列表紧跟一段时间或直到关键字,部分 if语句中的测试,&&和或||列表,......
子shell后跟" ||退出$?"显然算作一个命令清单;并且bash -e标志不适用于子shell内的任何命令。试试吧:
$ set -e
$ ( echo before the error; false; echo after the error, status $?; ) || echo after the subshell, status $?
before the error
after the error, status 1
$
因为子shell后跟||,所以"在错误后回显"即使使用set -e也可以运行。不仅如此,子shell退出0,因为" echo"跑了。所以" ||退出$?"甚至不会运行"退出"。可能不是我们想要的!
据我所知,以下公式与bash版本兼容,无论他们是否尊重bash -e在子shell之后。如果-e标志恰好被重置,它甚至可以正常运行:
在bash脚本中每个子shell的右括号后立即添加以下行:
case $?/$- in ( 0/* ) ;; ( */*e* ) exit $? ;; esac # honor bash -e flag when subshell returns