我在bash函数中使用短路评估(使用&&
和||
),我不明白我看到的行为。如果第一个数字不大于第二个,我希望函数返回:
[[ 5 > 2 ]] && echo true || echo false && return
# ^ ^ ^
# true so do this not this && this
[[ 5 > 8 ]] && echo true || echo false && return
# ^ ^ ^
# false so don't do this do this && this
但是在任何一种情况下函数都会返回无论第一个命令的状态如何,为什么return
命令都会执行?
而不是return
我尝试了break
,但由于不在循环内,它不起作用。
return
似乎在这两种情况下执行?stmt1 && stmt2 || stmt3 && stmt4
被评估为
( ( stmt1 && stmt2 ) || stmt3 ) && stmt4
即从左到右。
所以逻辑是
Execute stmt1 If it succeeds, then execute stmt2 endif If stmt1 succeeds and stmt2 succeeds, then (do nothing here) else # i.e., if stmt1 fails, OR stmt1 succeeds and then stmt2 fails execute stmt3 endif If stmt1 succeeds and stmt2 succeeds, OR stmt3 succeeds, then execute stmt4 endif
由于stmt2
和stmt3
都是echo
语句,它们都总是成功,所以stmt4
(return
语句)总是被执行。
我怀疑你在期待
( stmt1 && stmt2 ) || ( stmt3 && stmt4 )
并且您可以通过键入括号来获得该行为(通常),就像这样:
( [[ 5 > N ]] && echo true ) || ( echo false && return ) # No, don’t do this
或括号:
{ [[ 5 > N ]] && echo true; } || { echo false && return; }
请注意,在{
和}
之前的分号后必须有空格。
还要注意,使用括号,命令在子shell中运行,而使用大括号,它们不会(它们在主shell上下文中运行)。在您的特定代码示例中,您必须使用大括号(至少对于||
之后的部分),因为return
在子shell中运行时没有任何效果。
使用if
而不是逻辑运算符。
if [[ 5 > 8 ]]
then echo true
else
echo false
return
fi
有关运算符如何组合的说明,请参阅precedence of the shell logical operators。