如何使具有多个条件的 while 循环在真实条件处停止?

如何使具有多个条件的 while 循环在真实条件处停止?

我提供了一个 while 循环,如下所示

#!/bin/bash
number1=1
while [ -z "$number2" ] | [ "$number2" == 404 ] & [ "$number2" != 200 ] & [ "$number1" -lt 13 ]; do
  #number2=$(some command which can actually get a number)
  number2=200 # <<< e.g. a command that would return 
  let number1=number1+1
done

这就是我需要做的

如果number2为 null 则执行循环
如果number2为 404 则执行循环
如果number2为 200 则不执行循环
执行循环直至number1为 12

当我尝试循环时number2=200它不会停止。看来我遇到了让它停在哪里number2的挑战200

如何编写该语句,以便在number2=200有替代方案时停止 while 循环?

答案1

如果 number2 为 null,则执行循环
如果 number2 为 404,则执行循环
如果 number2 为 200,则不执行循环
执行循环,直到 number1 为 12

换句话说,重复只要(number2 is null OR number2 = 404) AND (number2 != 200) AND (number1 <= 12)。请注意,此处需要某种分组,以使 AND 和 OR 的优先级明确。 (在 Bash 中,&&and||从左到右进行操作,但 AND 运算符的绑定通常比 OR 运算符的结合力更强。)

虽然你没有说 的其他值会发生什么number2,所以我们不妨放弃前两个条件,因为如果number2为 null 或 404,那么它不能是 200。所以我们得到(number2 != 200) AND (number1 <= 12)

这里,

while [ -z "$number2" ] | [ "$number2" == 404 ] & [ "$number2" != 200 ] & [ "$number1" -lt 13 ]; do ...

你有|and&而不是||and &&|表示管道,&在后台运行上述命令。因此,上面的代码将并行运行三个命令:一个管道包含两个测试,另一个管道包含一个测试,两者都在后台运行;以及在前台进行的一项测试。这没有多大意义。我&&||上面提到过,这些是 Bash 中的逻辑条件运算符。

简化的形式是:

while [ "$number2" != 200 ] && [ "$number1" -le 12 ]; do ...

(您可能还想使用比“number1”和“number2”更具描述性的变量名称。)

答案2

shell 中的逻辑运算符是&&||。和确实&|非常不同的事情(启动后台任务并分别在两个进程之间建立管道)。


#!/bin/sh

number1=1

while [ "$number1" -le 12 ]; do

    number2=$( some command )

    case $number2 in
        200)
            break
            ;;
        ""|404)
            # nothing
            ;;
        *)
            printf 'Unexpected: number2 = %s\n' "$number2" >&2
            exit 1
    esac

    number1=$(( number1 + 1 ))

done

中的数字看起来像 HTTP 状态代码。测试上述语句$number2中的值将允许您在给定任意数量的状态代码的情况下选择正确的操作,而不会使 shell 代码成为一堆笨拙的-statements。例如,caseif任何客户端或服务器故障代码可以由该模式触发4??|5??

这也在逻辑上分离了两个变量的语义。该number1变量控制迭代次数,同时number2严格控制根据神秘命令的结果采取的操作。

相关内容