Bash条件对我来说不清楚

Noq*_*rax 1 bash if-statement

我有bash条件的问题,特别是在"if"结构中.有一个if条件的例子:

while [[ $BUT_O1 -eq false && $BUT_O2 -eq false && $BUT_O3 -eq false ]]
do
...
done
Run Code Online (Sandbox Code Playgroud)

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

PS我读了bash脚本如何,但它仍然不清楚我.我甚至不明白为什么0 =真,在大多数语言中1 =真.

Mar*_*eed 5

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

if (( 0 )); then
  echo "0 is true"
else
  echo "0 is false"
fi
# => 0 is false
Run Code Online (Sandbox Code Playgroud)

但正常的壳"布尔表达式"(13759 if,while等)不会在数字操作; 它按命令运行.shell运行命令,如果命令成功,则表示为true; 如果命令失败,则计为false.(在上面的示例中,((如果给定的表达式的数值非零,则返回成功的命令.)

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

关于你的代码.您正在使用-eq,它进行数字比较,但false不是数字(除非您创建一个以false数值命名的变量).在数字表达式中-eq,非数字字符串都被视为0.我怀疑你在某些时候将变量设置为true- 这仍然不是一个数字,因此仍被视为0 -eq.那是:

if [[ true -eq false ]]; then
  echo "Whoa."
fi
# => Whoa.
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

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

while (( ! (BUT_01 || BUT_02 || BUT03) )); do
Run Code Online (Sandbox Code Playgroud)

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

declare -i false=0 true=1
Run Code Online (Sandbox Code Playgroud)

我想你可能已经被存在甩出的命令 truefalse.但命令名仍然只是shell的字符串.如果你这样做:

if true; then
Run Code Online (Sandbox Code Playgroud)

shell看到了字符串"true",但它在一个寻找运行命令的地方看到它.因此它运行该命令,它只执行退出代码0(成功)立即退出.同样适用false,除了它以非零代码(特别是1)退出.