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

Why does command after `||` execute even if prior command succeeds?

我在 bash 函数中使用短路计算(使用 &&||), 而且我不明白我所看到的行为。我希望函数 return 如果第一个数不大于第二个数:

[[ 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, 但由于不在循环中,它不起作用。

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

  2. 我还能如何结束 运行 函数?

使用 if 而不是逻辑运算符。

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

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

    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

因为 stmt<sub>2</sub>stmt<sub>3</sub> 都是 echo 语句,它们总是成功, 所以 stmt<sub>4</sub>return 语句) 总是被执行。

我怀疑你在期待

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

并且您可以通过键入括号来获得该行为(通常), 就这样:

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

或大括号:

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

请注意,您必须{ 之后有空格 和 }.

前的分号

另请注意,带括号的命令 运行 在 subshells 中, 而对于大括号,它们不会(它们在主 shell 上下文中 运行)。 在您的具体代码示例中,您必须使用大括号 (至少对于 || 之后的部分), 因为 return 如果它是 运行 在子 shell 中没有任何效果。