Bash条件对我来说不清楚

时间:2015-08-29 12:29:47

标签: bash if-statement

我遇到了bash条件的问题,尤其是"如果"结构。 有一个if条件的例子:

while [[ $BUT_O1 -eq false && $BUT_O2 -eq false && $BUT_O3 -eq false ]]
do
...
done

当其中一个变量成真时,我需要停止该循环。

P.S。我读了bash脚本如何,但对我来说仍然不清楚。我甚至没有'理解为什么0 =真,当在大多数语言中时1 =真。

1 个答案:

答案 0 :(得分:5)

如果你正在做算术,0是假的,非零是真的,就像在其他语言中一样:

if (( 0 )); then
  echo "0 is true"
else
  echo "0 is false"
fi
# => 0 is false

但正常的shell“布尔表达式”(由ifwhile等使用)不对数字起作用;它按命令运行。 shell运行命令,如果命令成功,则表示为true;如果命令失败,则计为false。 (在上面的示例中,((是一个命令,如果给它的表达式的数值非零,则返回成功。)

命令指示它们是否以一个字节的“退出代码”值成功返回shell。在这种情况下,0表示成功,非零表示失败 - 因为命令通常只有一种方法可以成功,但很多方面都可能出错。因此,程序可以使用其退出代码告诉shell不仅 它失败了,而且还特别 它失败了。 (具体数字不会影响布尔值,这仍然是假的,但退出代码也可以作为$?中的数字使用,因此脚本可以自由检查它。)

转到您的代码。您正在使用-eq进行数字比较,但false不是数字(除非您使用数值创建名为false的变量)。在像-eq这样的数字表达式中,非数字字符串都被视为0.我怀疑您在某些时候将变量设置为true - 这仍然不是数字,所以仍然被视为0 -eq。那就是:

if [[ true -eq false ]]; then
  echo "Whoa."
fi
# => Whoa.

我最好的猜测是你可能想要更像这样的东西:

declare -i BUT_01=0 BUT_02=0 BUT_03=0
while (( !BUT_O1 && !BUT_O2 && !BUT_O3 )); do
    ....
    if # we're done with BUT_01
    then
      BUT_01=1
    fi
    ... # and so on for the others
done

或者您可能更喜欢DeMorgan的版本:

while (( ! (BUT_01 || BUT_02 || BUT03) )); do

无论哪种方式,使用数字值truefalse,而不是简单字符串的10。如果您真的想使用符号名称,可以预先声明它们:

declare -i false=0 true=1

我认为您可能因命令 truefalse的存在而被抛弃。但命令名仍然只是shell的字符串。如果你这样做:

if true; then

shell会看到字符串"true",但它会在查找要运行的命令的位置看到它。因此它运行该命令,它只执行退出代码0(成功)立即退出。 false也是如此,除了它以非零代码(特别是1)退出。