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

"... && ... || ..." (short-circuiting boolean) not identical to "if ...; then ...; else ...; fi"

我刚刚通过编写 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 块作为最后一个语句在错误条件下表现不佳,这些块似乎 "unsafe"使用。

因为 || 的功能是如果其左侧 returns 非零则执行其右侧,而 false 确实如此。

&&/|| 不是 if/else,也不是 ?: 三元运算符 - 它是一对链式独立运算。

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

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

相当于:

true && true || true

所以 true && true 的计算结果为 true,而 shell "short-circuits"(即不计算){ 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中的相同shell).