单引号问题 运行 Azure CLI 命令

Issue with single quotes running Azure CLI command

我的脚本片段如下:

要完成的最终目标是创建一个 Azure DevOps 变量组并将来自另一个变量组的键值注入其中(新创建的 Azure DevOps 变量组)

set -x
echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" | az devops login --organization https://dev.azure.com/tempcompenergydev
az devops configure --defaults organization=https://dev.azure.com/tempcompenergydev project=Discovery
export target_backend=automation
export target_backend="tempcomp.Sales.Configuration.Spa ${target_backend}"
export new_env="abc"

values=(addressSearchBaseUrl addressSearchSubscriptionKey cacheUrl calendarApiUrl checkoutBffApiUrl cpCode)

az_create_options=""

for ptr in "${values[@]}"
do
    result=$(
      az pipelines variable-group list --group-name "${target_backend}" | jq '.[0].variables.'${ptr}'.value'
        
    )
    printf "%s\t%s\t%d\n" "$ptr" "$result" $?

    # add the variable and value to the array
    az_create_options="${az_create_options} ${ptr}=${result}"
done

az pipelines variable-group create \
    --name "test ${new_env}" \
  --variables "${az_create_options}"

但是,当上面的命令执行时,我得到如下意外输出:

+ az pipelines variable-group create --name 'test abc' --variables ' addressSearchBaseUrl="https://qtruat-api.platform.tempcomp.com.au/shared" addressSearchSubscriptionKey="xxxxxxxxxxxxxxxxxxx" cacheUrl="https://tempcompdstqtruat.digital.tempcomp.com.au/app/config" calendarApiUrl="https://qtruat-api.platform.tempcomp.com.au/sales/calendar/v1;rev=deadpool/AvailableDates/EnergyMovers/" checkoutBffApiUrl="https://qtruat-api.platform.tempcomp.com.au/sales/checkout-experience/v1;rev=deadpool/" cpCode="1067076"'
 cpCode "1067076"   0
 WARNING: Command group 'pipelines variable-group' is in preview and under development. Reference and support levels: https://aka.ms/CLI_refstatus
 {
   "authorized": false,
   "description": null,
   "id": 1572,
   "name": "test abc",
   "providerData": null,
   "type": "Vsts",
   "variables": {
     "addressSearchBaseUrl": {
       "isSecret": null,
       "value": "\"https://qtruat-api.platform.tempcomp.com.au/shared\" addressSearchSubscriptionKey=\"xxxxxxxxxxxxxxxxxxxxxxxxx\" cacheUrl=\"https://tempcompdstqtruat.digital.tempcomp.com.au/app/config\" calendarApiUrl=\"https://qtruat-api.platform.tempcomp.com.au/sales/calendar/v1;rev=deadpool/AvailableDates/EnergyMovers/\" checkoutBffApiUrl=\"https://qtruat-api.platform.tempcomp.com.au/sales/checkout-experience/v1;rev=deadpool/\" cpCode=\"1067076\""
     }
   }
 }
 ##[section]Finishing: Bash Script

附带说明一下,如果我手动 运行,我会得到正确的响应。示例如下:

az pipelines variable-group create --name "test abc" --variables addressSearchBaseUr="https://qtruat-api.platform.tempcomp.com.au/shared"  addressSearchSubscriptionKey="xxxxxxxxxxxxxxxxxxxxxxxxx"  cacheUrl="https://tempcompdstqtruat.digital.tempcomp.com.au/app/config"  calendarApiUrl="https://qtruat-api.platform.tempcomp.com.au/sales/calendar/v1;rev=deadpool/AvailableDates/EnergyMovers/"  checkoutBffApiUrl="https://qtruat-api.platform.tempcomp.com.au/sales/checkout-experience/v1;rev=deadpool/"  cpCode="1067076"

输出:

 + az pipelines variable-group create --name 'test abc' --variables addressSearchBaseUr=https://qtruat-api.platform.tempcomp.com.au/shared addressSearchSubscriptionKey=xxxxxxxxxxxxxxxxxxx cacheUrl=https://tempcompdstqtruat.digital.tempcomp.com.au/app/config 'calendarApiUrl=https://qtruat-api.platform.tempcomp.com.au/sales/calendar/v1;rev=deadpool/AvailableDates/EnergyMovers/' 'checkoutBffApiUrl=https://qtruat-api.platform.tempcomp.com.au/sales/checkout-experience/v1;rev=deadpool/' cpCode=1067076
 WARNING: Command group 'pipelines variable-group' is in preview and under development. Reference and support levels: https://aka.ms/CLI_refstatus
 {
   "authorized": false,
   "description": null,
   "id": 1573,
   "name": "test abc",
   "providerData": null,
   "type": "Vsts",
   "variables": {
     "addressSearchBaseUr": {
       "isSecret": null,
       "value": "https://qtruat-api.platform.tempcomp.com.au/shared"
     },
     "addressSearchSubscriptionKey": {
       "isSecret": null,
       "value": "xxxxxxxxxx"
     },
     "cacheUrl": {
       "isSecret": null,
       "value": "https://tempcompdstqtruat.digital.tempcomp.com.au/app/config"
     },
     "calendarApiUrl": {
       "isSecret": null,
       "value": "https://qtruat-api.platform.tempcomp.com.au/sales/calendar/v1;rev=deadpool/AvailableDates/EnergyMovers/"
     },
     "checkoutBffApiUrl": {
       "isSecret": null,
       "value": "https://qtruat-api.platform.tempcomp.com.au/sales/checkout-experience/v1;rev=deadpool/"
     },
     "cpCode": {
       "isSecret": null,
       "value": "1067076"
     }
   }
 }
 ##[section]Finishing: Bash Script

这可能会有所帮助....

有一个关于 Azure 托管代理如何向 ADO using the az-pipelines command 进行身份验证的未决问题。

感觉这是相关的,但如果不能随意回复,我会删除答案。

变通

我不是 bash 专业人士,但我找到了适合您的解决方案。我认为问题的核心在于,当您在那里打印数组时,它会将 --variables 参数集视为一个长字符串。所以你得到这个...

az pipelines variable-group create --name "test ${new_env}" --variables ' addressSearchBaseUrl="val" addressSearchSubscriptionKey="val" ...'

而不是这个...

az pipelines variable-group create --name "test ${new_env}" --variables addressSearchBaseUrl="val" addressSearchSubscriptionKey="val" ...

不好: 我想你 可以 使用 eval 来解决这个问题,而不是打印出参数,而是使用 eval 在几乎任何情况下都不建议这样做。

好: 相反,我认为可以用不同的方式解决这个问题。此脚本不会一次创建所有变量的批处理,而是一次将所需变量复制到一个新组:

set -x
echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" | az devops login --organization https://dev.azure.com/tempcompenergydev
az devops configure --defaults organization=https://dev.azure.com/tempcompenergydev project=Discovery
export target_backend=automation
export target_backend="tempcomp.Sales.Configuration.Spa ${target_backend}"
export new_env="abc"

values=(addressSearchBaseUrl addressSearchSubscriptionKey cacheUrl calendarApiUrl checkoutBffApiUrl cpCode)

az_create_options=()

for ptr in "${values[@]}"
do
   result=$( az pipelines variable-group list --group-name "${target_backend}" | jq '.[0].variables.'${ptr}'.value' )
   echo "$result"
   # Result from this az command always wraps the response in double quotes. They should be removed.
   stripQuote=$( echo $result | sed 's/^.//;s/.$//' )
   printf "%s\t%s\t%d\n" "$ptr" "$stripQuote" $?
  
   # add the variable and value to the array
   # When adding this way you ensure each key|value pair gets added as a separate element
   az_create_options=("${az_create_options[@]}" "${ptr}|${stripQuote}")
   # ^ Note on this: The | is used because there needs to be a way to separate
   #   the key from the value. What you're really trying to do here is an
   #   Associative Array, but not all versions of bash support that out of the
   #   box. This is a bit of a hack to get the same result. CAUTION if your
   #   variable value contains a | character in it, it will cause problems
   #   during the copy.
done
 
# Create the new group, save the group id (would be best to add a check to see if the group by this name exists or not first)
groupId=$( az pipelines variable-group create  --name "test ${new_env}"  --variables bootstrap="start" | jq '.id' )
 
 
for var in "${az_create_options[@]}"
do
   # Split the key|value pair at the | character and use the set to create the new variable in the new group
   # Some check could also be added here to see if the variable already exists in the new group or not if you want to use this create or update an existing group
   arrVar=(${var//|/ })
   echo "Parsing variable ${arrVar[0]} with val of ${arrVar[1]}"
   az pipelines variable-group variable create \
       --id "${groupId}" \
       --name "${arrVar[0]}" \
       --value "${arrVar[1]}"
done
 
# This is needed cause the az command is dumb and won't let you create a group in the first place without a --variables argument. So I had it create a dummy var and then delete it
az pipelines variable-group variable delete --id "${groupId}" --name "bootstrap" --yes

调用注意事项

  1. 我建议尽可能使用 关联数组 而不是我在此处列出的数组。但是,关联数组仅在 bash v4 或更高版本中受支持。使用 bash --version 看看您是否能够使用它们。请参阅 this guide 作为您可以使用这些方法的一些示例。

  2. 如果使用我的方法,请注意正在复制的变量值中的任何 | 字符都会导致脚本失败。您可能需要选择不同的分隔符来拆分。

  3. az pipelines variable-group list命令的输出将给出包装在"中的变量的值。如果您尝试转身并在变量创建命令中抛出您从列表中获得的确切结果,您将在您的组中获得一堆变量,其值类似于

    {
      "variable": {
        "isSecret": null,
        "value": "\”value\”"
      }
    }
    

    而不是

    {
      "variable": {
        "isSecret": null,
        "value": "value"
      }
    }
    
  4. az 命令很笨,如果没有 --variables 参数,它不会让您首先创建一个新的变量组。所以我让它创建了一个虚拟变量 bootstrap="start" 然后删除它。

  5. 正如我提到的,可能有更好的方法来打印出我缺少的数组。如果您知道更好的方法,欢迎对我的 post 发表评论。