do whileを使用して無限ループを作成し、失敗したときに中断する方法は?

do whileを使用して無限ループを作成し、失敗したときに中断する方法は?

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

最初の呼び出しが成功すると、上記のスクリプトは正しく機能します。しかし、私は次のシナリオで何かを期待しています

  • 値が(現在動作中)$AMI_STATEに等しい場合は、ループを中断する必要があります。"available""failed"
  • 値が等しい場合は、期待値が$AMI_STATE満たさ"pending"れるまでループを続行する必要があります。

答え1

AMI_STATEの値が...と等しいときにループを実行したいので、これをpending書いてください。

while
    AMI_STATE=$(aws ec2 describe-images --region "$REGION" --image-ids $US_EAST_AMI | jq -r .Images[].State) &&
    [ "$AMI_STATE" = "pending" ]
do
    sleep 10
done
case $AMI_STATE in
    "") echo "Something went wrong: unable to retrieve AMI state";;
    available) echo "Now the AMI is available in the $REGION region";;
    failed) echo "The AMI has failed";;
    *) echo "AMI in weird state: $AMI_STATE";;
esac

答え2

単純な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

ここでもケースを選択することをお勧めします。

#!/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

bashのマニュアルで両方を読むことができます。3.2.5.2 条件付き構成

あるいは、無限のwhileループを放棄して代わりに使用することもできます。ループまで:

#!/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

状態が利用可能になるまで、必要なだけ繰り返されます。適切なエラー処理がなければ、これは簡単に無限ループに変わります。 (失敗以外の問題を引き起こす可能性のある状態がないことを確認してください)

関連情報