为什么即使先前的命令成功执行,`||`之后的命令仍会执行?

时间:2019-04-13 04:51:15

标签: bash operators

我在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, 但由于不在循环中而无法正常工作。

  1. 为什么在这两种情况下都执行return

  2. 我还能如何终止正在运行的功能?

2 个答案:

答案 0 :(得分:4)

    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

stmt2stmt3起 都是echo语句,它们总是成功, 因此stmt4return语句) 总是执行。

我怀疑你在期待

( stmt1  &&  stmt2 )  ||  ( stmt3  &&  stmt4 )

,您可以通过键入括号来获得该行为(一般而言), 就是这样:

 ( [[ 5 > N ]] && echo true )  ||  ( echo false && return )         # No, don’t do this

或大括号:

{ [[ 5 > N ]] && echo true; }  ||  { echo false && return; }

请注意,您 必须 必须在{{1} 和在{之前的分号。

还要注意,带括号的命令在子外壳中运行, 而使用花括号时,它们就不会(它们在主shell上下文中运行)。 在您的特定代码示例中,必须使用花括号 (至少{{1}之后的部分), 因为}如果在子shell中运行没有任何作用。

答案 1 :(得分:2)

使用if代替逻辑运算符。

if [[ 5 > 8 ]]
then echo true
else
    echo false
    return
fi

请参阅precedence of the shell logical operators,以获取有关运算符如何组合的说明。