如何使用 do while 进行无限循环并在失败时中断?

Rav*_*ran 3 shell bash shell-script

我正在尝试检查 AWS AMI 的状态并在状态为 时执行一些命令available。下面是我实现这一目标的小脚本。

#!/usr/bin/env bash

REGION="us-east-1"
US_EAST_AMI="ami-0130c3a072f3832ff"

while :
do
      AMI_STATE=$(aws ec2 describe-images --region "$REGION" --image-ids $US_EAST_AMI | jq -r .Images[].State)

        [ "$AMI_STATE" == "available" ] && echo "Now the AMI is available in the $REGION region" && break
        sleep 10
done
Run Code Online (Sandbox Code Playgroud)

如果第一次调用成功,上面的脚本就可以正常工作。但我期待以下场景的一些东西

  • 如果 的值$AMI_STATE等于"available"(当前正在工作),"failed"则应该打破循环
  • 如果 的值$AMI_STATE等于"pending",则循环应继续,直到满足预期值。

Gil*_*il' 8

你想在 的值AMI_STATE等于pending\xe2\x80\xa6 时运行循环,所以就这样写。

\n
while\n    AMI_STATE=$(aws ec2 describe-images --region "$REGION" --image-ids $US_EAST_AMI | jq -r .Images[].State) &&\n    [ "$AMI_STATE" = "pending" ]\ndo\n    sleep 10\ndone\ncase $AMI_STATE in\n    "") echo "Something went wrong: unable to retrieve AMI state";;\n    available) echo "Now the AMI is available in the $REGION region";;\n    failed) echo "The AMI has failed";;\n    *) echo "AMI in weird state: $AMI_STATE";;\nesac\n
Run Code Online (Sandbox Code Playgroud)\n


jes*_*e_b 5

您可以使用一个简单的 if 构造:

#!/usr/bin/env bash

region="us-east-1"
us_east_ami="ami-0130c3a072f3832ff"

while :
do
    ami_state=$(aws ec2 describe-images --region "$region" --image-ids "$us_east_ami" | jq -r .Images[].State)
    if [[ $ami_state == available ]]; then
        echo "Now the AMI is available in the $region region"
        break
    elif [[ $ami_state == failed ]]; then
        echo "AMI is failed in $region region"
        break
    fi
    sleep 10
done
Run Code Online (Sandbox Code Playgroud)

case 在这里也是一个不错的选择:

#!/usr/bin/env bash

region="us-east-1"
us_east_ami="ami-0130c3a072f3832ff"

while :
do
    ami_state=$(aws ec2 describe-images --region "$region" --image-ids "$us_east_ami" | jq -r .Images[].State)

    case $ami_state in
        available)
            echo "Now the AMI is available in the $region region"
            break
        ;;
        failed)
            echo "AMI is failed in $region region"
            break
        ;;
        pending) echo "AMI is still pending in $region region";;
        *)
            echo "AMI is in unhandled state: $ami_state"
            break
        ;;
    esac
    sleep 10
done
Run Code Online (Sandbox Code Playgroud)

您可以在 bash 手册3.2.5.2 Conditional Constructs中阅读相关内容

或者,您可以考虑放弃无限 while 循环,转而使用Until 循环

#!/usr/bin/env bash

region="us-east-1"
us_east_ami="ami-0130c3a072f3832ff"

until [[ $ami_state == available ]]; do
    if [[ $ami_state == failed ]]; then
        echo "AMI is in a failed state for $region region"
        break
    fi
    ami_state=$(aws ec2 describe-images --region "$region" --image-ids "$us_east_ami" | jq -r .Images[].State)
    sleep 10
done
Run Code Online (Sandbox Code Playgroud)

这将根据需要循环多次,直到状态可用。如果没有适当的错误处理,这很容易变成无限循环。(确保除了失败之外没有任何状态可能会造成问题)