首页 > 解决方案 > 如何在shell脚本中使用带有某些条件的循环

问题描述

我需要curl多次运行命令,每次都检查结果。我使用 for 循环来检查 的输出curl,并且我想在达到正确状态时退出循环。

第一次curl运行命令时,它会向我显示以下输出:

{
  "name": "organizations/org_name/operations/long_running_operation_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.apigee.v1.OperationMetadata",
    "operationType": "INSERT",
    "targetResourceName": "organizations/org_name",
    "state": "IN_PROGRESS"
  }
}

完成需要时间,这就是为什么它说IN_PROGRESS。大约花了 30 到 60 秒,如果我们curl在 30 到 60 秒后运行相同的命令,那么它将显示以下输出:

{
  "error": {
    "code": 409,
    "message": "org graceful-path-310004 already associated with another project",
    "status": "ALREADY_EXISTS",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.RequestInfo",
        "requestId": "11430211642328568827"
      }
    ]
  }
}

这是我到目前为止的脚本:

test=$(curl -H "Authorization: Bearer $TOKEN" -X POST -H "content-type:application/json" \
  -d '{
    "name":"'"$ORG_NAME"'",
    "displayName":"'"$ORG_DISPLAY_NAME"'",
    "description":"'"$ORGANIZATION_DESCRIPTION"'",
    "runtimeType":"'"$RUNTIMETYPE"'",
    "analyticsRegion":"'"$ANALYTICS_REGION"'"
  }' \
          "https://apigee.googleapis.com/v1/organizations?parent=projects/$PROJECT_ID" | jq '.error.status')
echo $test
while [ $test = "ALREADY EXISTS" ||  $test != "IN_PROGRESS"  ]
do
        echo $test
        echo "Organization is creating"
        test=$(curl -H "Authorization: Bearer $TOKEN" -X POST -H "content-type:application/json" \
  -d '{
    "name":"'"$ORG_NAME"'",
    "displayName":"'"$ORG_DISPLAY_NAME"'",
    "description":"'"$ORGANIZATION_DESCRIPTION"'",
    "runtimeType":"'"$RUNTIMETYPE"'",
    "analyticsRegion":"'"$ANALYTICS_REGION"'"
  }' \
          "https://apigee.googleapis.com/v1/organizations?parent=projects/$PROJECT_ID" | jq '.error.status')
done
echo "exit from loop"

标签: linuxbashshellloops

解决方案


要减少重复代码,请使用函数。

此外,jq用于生成json 的最佳实践——它将安全地处理数据中的任何嵌入引号:

json() {
    jq  --arg name "$ORG_NAME" \
        --arg displayName "$ORG_DISPLAY_NAME" \
        --arg description "$ORGANIZATION_DESCRIPTION" \
        --arg runtimeType "$RUNTIMETYPE" \
        --arg analyticsRegion "$ANALYTICS_REGION" \
        --null-input --compact-output \
        '$ARGS.named'
}

errorStatus() {
    curl -H "Authorization: Bearer $TOKEN" \
         -X POST \
         -H "content-type:application/json" \
         -d "$(json)" \
          "${URL}?parent=projects/$PROJECT_ID" \
    | jq -r '.error.status'
}

while true; do
    status=$(errorStatus)
    [ "$status" = "ALREADY EXISTS" ] && break
done

echo "exit from loop"

while true; do some code; condition && break; done位是do-while循环的 bash 版本


推荐阅读