“为什么?”;假及&;“真的”;在Bash中不使用set-e退出?
为什么第三个案例返回成功,退出代码为0“为什么?”;假及&;“真的”;在Bash中不使用set-e退出?,bash,boolean,Bash,Boolean,为什么第三个案例返回成功,退出代码为0 case 1 ~$ bash -c 'set -e; false || true; echo success'; echo $? success 0 case 2 ~$ bash -c 'set -e; true || false; echo success'; echo $? success 0 case 3 ~$ bash -c 'set -e; false && true; echo success'; echo $? success
case 1 ~$ bash -c 'set -e; false || true; echo success'; echo $?
success
0
case 2 ~$ bash -c 'set -e; true || false; echo success'; echo $?
success
0
case 3 ~$ bash -c 'set -e; false && true; echo success'; echo $?
success
0
case 4 ~$ bash -c 'set -e; true && false; echo success'; echo $?
1
case 5 ~$ bash -c 'set -e; false || false; echo success'; echo $?
1
case 6 ~$ bash -c 'set -e; false && false; echo success'; echo $?
success
0
true&&false;echo success
返回echo
中的返回码,返回码为0
bash -c 'false && true'; echo $?
按预期生成1
。呸
旁白:
bash-c'set-e;假| |假;“呼应成功”;echo$?
产生返回代码1
,因为第二个命令不执行echo
(在false处停止,因为错误停止了当前命令),请注意,success
没有打印。set-e
有点微妙
从:
-e
当此选项处于启用状态时,当任何命令失败时(由于Shell错误的后果中列出的任何原因或通过返回退出)
状态大于零),外壳应立即退出,如同
在没有参数的情况下执行exit特殊内置实用程序,使用
下列例外情况:
多命令管道中任何单个命令的故障不得导致外壳退出。唯一的失败是
应考虑管道本身
在执行while、until、if或elif保留字之后的复合列表时,应忽略-e设置
从最开始!保留字,或AND-or列表的任何命令
除了最后一个。
如果子shell命令以外的复合命令的退出状态是在忽略-e时失败的结果,则
-e不适用于本命令
此要求分别适用于shell环境和每个子shell环境。例如,在:
set -e; (false; echo one) | cat; echo two
false命令导致子shell退出而不执行echo one;但是,执行echo two是因为
管道(错误;回声1)| cat为零
由于false&&true
是AND或or列表的一部分,并且false
不是最后一个,因此shell不会立即退出
因此执行echo success
,其返回代码为0
顺便问一下,您注意到案例6了吗?for集合-e
说:
如果失败的命令是在&&
或|
列表中执行的任何命令的[…]部分,则外壳程序不会退出,除了最后的&&
或|
之后的命令,[…]
有问题的命令列表是false&&true
。失败的命令是false
,它不是列表中的最后一个命令,因此shell不会退出。您看到的0
是echo success
的退出状态,根据该逻辑,案例4也应该写“success”,因为true&&false
是一个AND列表。梅尔波默恩回答中提到的例外在这里非常相关。@Heinzi:是的,我应该把它们联系起来,实际上它们增加了这一部分。。。哦,好吧。请看:set-e
很微妙,也很难解释(在不同的shell和发布版本之间有更微妙的实现差异),而且bash社区中有很大一部分人同意永远不应该使用它的主张。引用页面“它具有有用的语义,因此将其从工具箱中排除就是将其放入FUD。“@eckes:那只是某个模糊用户的意见。GreyCat和geirha有另一种观点。@eckes,……值得注意的是,GreyCat是该FAQ和BashGuide的主要作者,也是Freenode#bash IRC频道的主要负责人。如果有来自权威机构的争论,那么值得注意的是相关权威机构是谁。请随意根据权威机构进行争论-我认为使用没有set-e
的shell脚本通常是个坏主意。它确实强制执行正确的错误处理。这是值得的。