考虑两个条件表达式expr1
和expr2
,例如$i -eq $j
和$k -eq $l
。我们可以用bash
多种方式来写这个。这里有两种可能性
[[ expr1 || expr2 ]]
[[ expr1 ]] || [[ expr2 ]]
我相当确定我在这里看到了应该首选第二个的建议,但我找不到支持这一点的证据。
这是一个示例脚本,似乎证明没有区别:
for i in 0 1
do
for j in 0 1
do
for k in 0 1
do
for l in 0 1
do
if [[ $i -eq $j || $k -eq $l ]]; then printf "1-yes\t"; else printf "1-no\t"; fi
if [[ $i -eq $j ]] || [[ $k -eq $l ]]; then printf "2-yes\n"; else printf "2-no\n"; fi
done
done
done
done
输出显示两个条件构造产生相同的结果:
1-yes 2-yes
1-yes 2-yes
1-yes 2-yes
1-yes 2-yes
1-yes 2-yes
1-no 2-no
1-no 2-no
1-yes 2-yes
1-yes 2-yes
1-no 2-no
1-no 2-no
1-yes 2-yes
1-yes 2-yes
1-yes 2-yes
1-yes 2-yes
1-yes 2-yes
使用一种结构比使用另一种结构有什么好处吗?
对于奖励积分,相同的问题,但使用||
和概括为多个条件&&
。例如,[[ expr1 && expr2 || expr3 ]]
。
答案1
我认为您看到的建议是针对 POSIX 的嘘和/或test
兼作[
命令的命令,而不是[[
ksh 中出现的结构(感谢 Stéphane Chazelas 的提示),并且也用于 bash、zsh 和其他一些 shell 中。
在大多数语言(如 C)中,当已知子句为 true 或 false 时,无需根据操作来计算剩余部分:if true 不在逻辑之后或者跟随它,如果为 false 则不在逻辑之后和等等。这当然允许例如在指针为 NULL 时停止,而不是尝试在下一个子句中取消引用它。
但嘘的[ expr1 -o expr2 ]
构造(包括 bash 的实现)不会这样做:它总是评估双方,而当一方只想表达式1待评估。这样做可能是为了与test
命令实现兼容。另一方面,sh||
和&&
do 遵循通常的原则:如果不会改变结果,则不进行评估。
所以需要注意的区别是:
: > /tmp/effect #clear effect
if [ 1 -eq 1 -o $(echo 1; echo or-was-evaluated > /tmp/effect) -eq 1 ]; then
echo true;
fi
cat /tmp/effect
产生:
true
or-was-evaluated
上面的每个命令[
都可以替换为命令/usr/bin/[
的别名test
,之前使用过[
它内置到 shell 中。
接下来的两个构造:
: > /tmp/effect #clear effect
if [ 1 -eq 1 ] || [ $(echo 1; echo or-was-evaluated > /tmp/effect) -eq 1 ]; then
echo true;
fi
cat /tmp/effect
或者
: > /tmp/effect #clear effect
if [[ 1 -eq 1 || $(echo 1; echo or-was-evaluated > /tmp/effect) -eq 1 ]]; then
echo true;
fi
cat /tmp/effect
只会产生true
并留空effect
:||
行为正确,并且[[
也纠正了这个问题。
更新:
正如@StéphaneChazelas 评论的那样,我错过了与最初问题相关的几个差异。我将在这里提出最重要的一个(至少对我来说):操作员的优先级。
虽然 shell 不会考虑优先级:
if true || true && false; then
echo true
else
echo false
fi
产生(因为没有优先级,因此首先true || true
评估,然后&& false
):
false
[[ ]]
运算符内部&&
优先于||
:
if [[ 1 -eq 1 || 1 -eq 1 && 1 -eq 0 ]]; then
echo true
else
echo false
fi
产量(因为1 -eq 1 && 1 -eq 0
已分组,因此是 的第二个成员||
):
true
至少对于什,巴什,桀骜。
因此,与直接 shell 逻辑运算符[[ ]]
相比,行为得到了改进。[ ]