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

时间:2015-07-10 20:22:26

标签: bash shell unix 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

输出正确的结果:

10 > 5

尽管

i=10
     [ $i -lt 5 ] && {
    echo "$i < 5"
} || [ $i -gt 5 ] && {
    echo "$i > 5"
} || [ $i -eq 5 ] && {
    echo "$i = 5"
}

表现得很不寻常:

10 > 5
10 = 5

在我看来,当翻译寻求1时,它应该是这样的:

  

0&amp;&amp; {} || 1&amp;&amp; {} || 0&amp;&amp; {}

     

0所以0&amp;&amp; {}肯定是0;跳过{}

     

1表示必须检查{}以定义整个1 && {}

的值

因此结果为1,但执行的唯一{}仍在1之后。 但是,当我放置! {而不是{时,这一切都可行。

i=10
     [ $i -lt 5 ] && ! {
    echo "$i < 5"
} || [ $i -gt 5 ] && ! {
    echo "$i > 5"
} || [ $i -eq 5 ] && ! {
    echo "$i = 5"
}

WHY?我认为它会寻找1,因为它在0中找到了&&,它不会查看链中的其他表达式!

2 个答案:

答案 0 :(得分:5)

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

i=10
[ $i -lt 5 ] && 
echo "$i < 5" ||
[ $i -gt 5 ] &&
echo "$i > 5" || 
[ $i -eq 5 ] &&
echo "$i = 5"

它的工作方式是:

  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":这会返回成功,因此会跳转到...等等,有新行。我们已经完成了。

  5. &&||被称为短路运营商。

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

    A && B || C
    

    相同
    if A; then
        B
    else
        C
    fi
    

    它相当于

    if A; then
        if ! B; then
            C
        fi
    else
        C
    fi
    

答案 1 :(得分:4)

&&||从左到右进行评估。您的命令或多或少与此相同:

(((( false && { echo 1; true; } ) || true ) && { echo 2; true; } ) || false ) && { echo 3; true; }
  • false && { echo 1; true; }不打印任何内容,并评估为false
  • false || true评估为true
  • true && { echo 2; true; }打印2并评估为true
  • true || false评估为true
  • true && { echo 3; true; }打印3并评估为true

神秘解决了。