Bash

如果出現故障,如何使用 do while 和 break 進行無限循環?

  • August 17, 2022

我正在嘗試檢查 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",則循環應繼續,直到達到預期值。

您想在 的值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

您可以使用一個簡單的 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 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

這將根據需要循環多次,直到狀態可用。如果沒有適當的錯誤處理,這很容易變成無限循環。(確保除了 failed 之外沒有其他狀態會影響事情)

引用自:https://unix.stackexchange.com/questions/713936