“为什么?”;假及&;“真的”;在Bash中不使用set-e退出?

“为什么?”;假及&;“真的”;在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

为什么第三个案例返回成功,退出代码为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
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脚本通常是个坏主意。它确实强制执行正确的错误处理。这是值得的。