Shell:逻辑AND和OR而不是if-else

the*_*den 4 unix bash shell boolean zsh

我想知道为什么

i=10
  if [ $i -lt 5 ]; then
    echo "$i < 5"
elif [ $i -gt 5 ]; then
    echo "$i > 5"
elif [ $i -eq 5 ]; then
    echo "$i = 5"
fi
Run Code Online (Sandbox Code Playgroud)

输出正确的结果:

10 > 5
Run Code Online (Sandbox Code Playgroud)

i=10
     [ $i -lt 5 ] && {
    echo "$i < 5"
} || [ $i -gt 5 ] && {
    echo "$i > 5"
} || [ $i -eq 5 ] && {
    echo "$i = 5"
}
Run Code Online (Sandbox Code Playgroud)

表现得很不寻常:

10 > 5
10 = 5
Run Code Online (Sandbox Code Playgroud)

在我看来,当翻译寻求1s时,它应该像这样工作:

0 && {} || 1 && {} || 0 && {}

0所以0 && {}绝对是0; 跳跃{}

1表示必须检查{}以定义整数的值 1 && {}

所以结果是1,但是只{}执行了之后1.但是,当我放入! {而不是{s 时,这一切都能正常工作.

i=10
     [ $i -lt 5 ] && ! {
    echo "$i < 5"
} || [ $i -gt 5 ] && ! {
    echo "$i > 5"
} || [ $i -eq 5 ] && ! {
    echo "$i = 5"
}
Run Code Online (Sandbox Code Playgroud)

为什么?!我认为它寻求1如此的,因为它发现一个0&&它不看在链中的其他表情!

gei*_*rha 5

{...}没有区别,所以你拥有的就是这个:

i=10
[ $i -lt 5 ] && 
echo "$i < 5" ||
[ $i -gt 5 ] &&
echo "$i > 5" || 
[ $i -eq 5 ] &&
echo "$i = 5"
Run Code Online (Sandbox Code Playgroud)

它的工作方式是:

  1. [ $i -lt 5 ]:这是假的(返回故障),因此它跳转到下一个||,这[ $i -gt 5 ]下它.

  2. [ $i -gt 5 ]:这是真的(返回成功),所以它跳转到下一个&&,echo "$i > 5"跟随它.

  3. echo "$i > 5":这会返回成功,所以它跳转到下一个&&,它echo "$i = 5"跟随它.

  4. echo "$i = 5":这会返回成功,所以它跳转到...等等,有一个换行符.我们完成了.

&&并被||称为短路运营商.

编辑:进一步强调这一点,

A && B || C
Run Code Online (Sandbox Code Playgroud)

一样的

if A; then
    B
else
    C
fi
Run Code Online (Sandbox Code Playgroud)

它相当于

if A; then
    if ! B; then
        C
    fi
else
    C
fi
Run Code Online (Sandbox Code Playgroud)

  • 更具体地说,在shell中`X && Y || Z`不是**三元操作. (4认同)