【问题标题】:Compare String with list of strings in bash将字符串与 bash 中的字符串列表进行比较
【发布时间】:2021-10-11 07:19:51
【问题描述】:

我正在尝试将服务与可用服务名称列表进行比较,如果在列表中找到服务,则更新服务,否则部署服务。 但即使在列表变量中提供服务时,以下条件也仅部署新服务?

SERVNAME=ner
SERVICE=$(az ml service list -g $(ml_rg) --workspace-name $(ml_ws) --model-name $(model_name) --query "[].name")

if [[ "$SERVNAME" == "$SERVICE" ]];
then
   echo "Service Found: $(SERVNAME) and updating the service"
   az ml service update --name $(AKS_DEPLOYMENT_NAME) \
          --model '$(MODEL_NAME):$(MODEL_VERSION)' \
          --dc aksDeploymentConfig.json \
          --ic inferenceConfig.json \
          -e $(ml_env_name) --ev $(ml_env_version) \
          -g $(ml_rg) --workspace-name $(ml_ws) -v ;
else
   echo "Service Not found and starting deploying new service"
   az ml model deploy --name $(AKS_DEPLOYMENT_NAME) --model \
   '$(MODEL_NAME):$(MODEL_VERSION)' \
          --compute-target $(ml_aks_name) \
          --ic inferenceConfig.json \
          -e $(ml_env_name) --ev $(ml_env_version) \
          --dc aksDeploymentConfig.json \
          -g $(ml_rg) --workspace-name $(ml_ws) \
          --overwrite -v ;
fi

示例列表

SERVNAME="ner"
SERVICE=[ "ner", "aks-gpu-ner-0306210907", "aks-gpu-ner-30012231", "aks-gpu-ner-1305211336"]

【问题讨论】:

  • 这里有很多不正确的 bash 语法。看起来您正在使用 $( ) 来获取变量的值,但这是运行命令并获取其输出的语法;我想你想要${ }。说到这一点,像这样的变量引用应该几乎总是在双引号中(尤其不是单引号,因为它们可以防止变量扩展)。 shellcheck.net 会指出很多问题。此外,最后SERVICE 的示例值不是有效的语法;该值是否实际上包含括号和引号?
  • @GordonDavisson 是的带括号和引号的服务变量是运行“az ml service list”命令的结果。

标签: linux bash azure-devops azure-machine-learning-studio


【解决方案1】:

假设az ml 命令返回一个 json 数组字符串并且你想 检查数组是否包含变量SERVNAME 的值,你会 请尝试:

SERVNAME="ner"
SERVICE='[ "ner", "aks-gpu-ner-0306210907", "aks-gpu-ner-30012231", "aks-gpu-ner-1305211336"]'

if [[ $SERVICE =~ "\"$SERVNAME\"" ]]; then
    echo "Service Found"
    # put your command here to update the service
else
    echo "Service Not Found"
    # put your command here to deploy new service
fi

如果字符串$SERVICE 匹配,则正则表达式运算符$SERVICE =~ "\"$SERVNAME\"" 包含用双引号括起来的子字符串$SERVNAME

如果jq 可用,您也可以说:

result=$(echo "$SERVICE" | jq --arg var "$SERVNAME" '. | index($var)')
if [[ $result != "null" ]]; then
    echo "Service Found"
else
    echo "Service Not Found"
fi

【讨论】:

  • 该方法是否会检查是否与 SERVICE 列表中的 SERVNAME 完全匹配
  • 当然。至于第一种解决方案,请注意 rhs "$SERVNAME" 用双引号括起来。双引号不是 bash 脚本中经常使用的变量包装器而是 正则表达式的一部分。然后部分匹配不允许,例如"ner""aks-gpu-ner-0306210907"。第二个jq 解决方案也找到了完全匹配。
  • @tshiono 这是不正确的,在正则表达式版本中,双引号不作为模式的一部分进行匹配,而是视为意味着双引号部分应该按字面意思而不是正则表达式语法匹配。也就是说,.* 将匹配任何字符序列,但 ".*" 将只匹配一个文字句点后跟一个星号。您可以通过从SERVICE 列表中删除"ner" 或设置SERVNAME="gpu-ner" 来测试这一点——两者仍然匹配。您需要 if [[ $SERVICE =~ "\"$SERVNAME\"" ]] (同时具有文字 语法双引号)。
  • @GordonDavisson 感谢您指出我。年,你是对的。我已相应地更正了我的答案。 sree,你能看看我的更新吗?谢谢。
  • @tshiono 看起来不错,我更新了说明文字以匹配。
【解决方案2】:

Bash 没有列表,它有数组。

要检查数组是否包含值,请使用以下命令:

SERVNAME="ner"
SERVICE=("ner" "aks-gpu-ner-0306210907" "aks-gpu-ner-30012231" "aks-gpu-ner-1305211336")

if [[ " ${SERVICE[*]} " =~ " ${SERVNAME} " ]]; then
    echo "Match Found For Service: $SERVNAME"
else
    echo "Match Not Found For Service: $SERVNAME"
fi

【讨论】:

  • 变量是从 Azure devops 变量集引用的,服务变量是运行“az ml service list”命令的结果,所以这就是变量用括号和引号括起来的原因。
猜你喜欢
  • 2020-12-18
  • 1970-01-01
  • 2018-03-17
  • 2021-03-08
  • 2021-08-27
  • 1970-01-01
  • 2017-02-20
  • 2010-10-06
  • 1970-01-01
相关资源
最近更新 更多