我遇到了bash条件的问题,尤其是"如果"结构。 有一个if条件的例子:
while [[ $BUT_O1 -eq false && $BUT_O2 -eq false && $BUT_O3 -eq false ]]
do
...
done
当其中一个变量成真时,我需要停止该循环。
P.S。我读了bash脚本如何,但对我来说仍然不清楚。我甚至没有'理解为什么0 =真,当在大多数语言中时1 =真。
答案 0 :(得分:5)
如果你正在做算术,0是假的,非零是真的,就像在其他语言中一样:
if (( 0 )); then
echo "0 is true"
else
echo "0 is false"
fi
# => 0 is false
但正常的shell“布尔表达式”(由if
,while
等使用)不对数字起作用;它按命令运行。 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
无论哪种方式,使用数字值true
和false
,而不是简单字符串的1
和0
。如果您真的想使用符号名称,可以预先声明它们:
declare -i false=0 true=1
我认为您可能因命令 true
和false
的存在而被抛弃。但命令名仍然只是shell的字符串。如果你这样做:
if true; then
shell会看到字符串"true"
,但它会在查找要运行的命令的位置看到它。因此它运行该命令,它只执行退出代码0(成功)立即退出。 false
也是如此,除了它以非零代码(特别是1)退出。