bash - && 和 || 的执行顺序 在重击中
问题描述
我正在使用 Bash 完成一些基本练习,我对&&
and的操作顺序感到困惑||
。以下是一些可重现的示例。
# Example 1
true && false || echo pass
# pass
由于第一个true
被执行,&&
传递到false
并被false
执行(true && false
)。||
求值false
,因为false
左侧有 a,所以echo pass
被执行 ( false || echo pass
)。到目前为止,一切都很好。
示例 2
false && false || echo pass
# pass
由于第一个表达式是false
,&&
不执行第二个false
。但是,echo pass
因为左侧false || echo pass
为假而被打印。到目前为止一切都很好。
示例 3
[[ 2 -gt 3 ]] && echo t || echo f
# f
2
不大于3
,意味着echo t
不会被执行。但是,echo t || echo f
打印f
. 基于前面两个示例,echo t
应该返回一个非退出代码并且不在echo f
右侧执行。
我错过了什么?
解决方案
- 总的一般规则是:任何表达式都有最后执行的命令的退出代码。[*]
- 分组。
a && b || c
等于( a && b ) || c
,即。左边是一大表情。&&
并且||
具有相同的优先级,它们从左到右执行。
最后执行的命令[[ 2 -gt 3 ]] && echo t
是[[ 2 -gt 3 ]]
,它返回非零。所以整个[[ 2 -gt 3 ]] && echo t
表达式的退出状态是非零的——最后一个命令执行的退出状态。
[[ 2 -gt 3 ]] && echo t || echo f
( [[ 2 -gt 3 ]] && echo t ) || echo f
( false && echo t ) || echo f
( false ) || echo f
echo f
[*] - 该规则适用于命令列表( )
{ }
&&
||
以及复合结构while
if
case
等中的任何命令。你可以做一些有趣的事情,比如if case "$line" in a) false; ;; esac; then echo "line is not a"; fi
. 的退出状态case
等于最后执行的命令的退出状态,false
以防line
匹配a)
。