“ ... && ... || ...”(短路布尔值)与“ if ...; then ...; else ...; fi”不同

时间:2019-06-20 12:50:28

标签: bash conditional-statements codeblocks

通过编写if / then / else块的替代形式,我刚刚得到了意外的结果。

> #this is the behaviour I expect:  
> if [[ 1 -eq 1 ]]; then echo "good"; false; else   echo "bad"; fi
good

> #assuming no error in the first block these brackets behave okay as well:
> [[ 1 -eq 1 ]] && { echo "good"; } || { echo "bad"; }
good

> #this however allows the process to jump into the first AND second block
> [[ 1 -eq 1 ]] && { echo "good"; false; } || { echo "bad"; }
good
bad

为什么花括号方法将过程传递到第二个块。我知道有一些语句要求在块的末尾必须有;,但是如果bash块在错误情况下表现不佳(作为最后一条语句),则使用这些块似乎“不安全”。

2 个答案:

答案 0 :(得分:2)

因为||的功能是在其左侧返回非零的情况下执行其右侧,false会这样做。

&& / ||不是if / else,也不是?:三元运算符-它是一对成对的独立操作。

答案 1 :(得分:1)

shell中的&&||运算符使用每个语句的返回值(退出代码)。在{ }内的复合语句中,最后一条命令的退出状态很重要。

[[ 1 -eq 1 ]] && { echo "good"; } || { echo "bad"; }

等效于:

true && true || true

因此true && true的值为true,并且由于{ echo "bad"; }为真,因此外壳会“短路”(即不评估)true || anything

[[ 1 -eq 1 ]] && { echo "good"; false; } || { echo "bad"; }

等效于:

true && false || true

在这种情况下,true && false的计算结果为false,shell必须对完整的表达式进行评估。

if / else代码采用第一个分支,因为[[ 1 -eq 1 ]]的退出代码为0(与外壳程序中的true相同)