为什么即使先前的命令成功,`||` 之后的命令也会执行?
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
,
但由于不在循环中,它不起作用。
为什么 return
似乎在这两种情况下都执行?
我还能如何结束 运行 函数?
使用 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 中没有任何效果。
我在 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
,
但由于不在循环中,它不起作用。
为什么
return
似乎在这两种情况下都执行?我还能如何结束 运行 函数?
使用 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 中没有任何效果。