【问题标题】:Space separated values; how to provide a value containing a space空格分隔值;如何提供包含空格的值
【发布时间】:2018-11-17 09:07:24
【问题描述】:

我正在创建一个 bash 脚本以通过 Azure CLI 预配多个 Azure 资源。到目前为止一切顺利,但是我在标记资源时遇到了问题。

我的目标是将多个标签存储在一个变量中,并将该变量提供给脚本中几个az 命令的--tags 选项。然而问题是值中的空格将被解释​​为新键。

如果我们以命令az group update(将更新资源组)为例,docs 会声明以下关于 --tags 选项的信息:​​

--tags 'key[=value]' 格式的空格分隔标签。使用“”清除现有标签。

当一个值(或键)包含空格时,它必须用引号引起来。 因此,当我们将键值对直接提供给命令时,包括带有空格的值,如下例所示,结果将符合预期:

az group update --tags owner="FirstName LastName" application=coolapp --name resource-group-name

结果将是两个标签已添加到资源组:

{
  "id": "/subscriptions/1e42c44c-bc55-4b8a-b35e-de1dfbcfe481/resourceGroups/resource-group-name",
  "location": "westeurope",
  "managedBy": null,
  "name": "resource-group-name",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": {
    "application": "coolapp",
    "owner": "FirstName LastName"
  }
}

但是,当我们将在上一步中使用的相同值存储在变量中时,就会出现问题。

tag='owner="FirstName LastName" application=coolapp'

我使用echo $tag 来验证变量是否包含与我们在上一个示例中提供给 --tags 选项的值完全相同的值:

owner="FirstName LastName" application=coolapp

但是当我们将这个标签变量提供给命令的标签选项时,如下一行所示:

az group update --tags $tag --name resource-group-name

结果将是三个标签,而不是预期的两个:

{
  "id": "/subscriptions/1e42c44c-bc55-4b8a-b35e-de1dfbcfe481/resourceGroups/resource-group-name",
  "location": "westeurope",
  "managedBy": null,
  "name": "resource-group-name",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": {
    "LastName\"": "",
    "application": "coolapp",
    "owner": "\"FirstName"
  }
}

我已经尝试通过以下方式定义变量,但到目前为止没有运气:

tag="owner=FirstName LastName application=coolapp"
tag=owner="Firstname Lastname" application=cool-name
tag='`owner="Firstname Lastname" application=cool-name`'

我什至尝试将变量定义为数组并将其提供给命令,如下一行所示,但也没有提供正确的结果:

tag=(owner="Firstname Lastname" application=cool-name)

az group update --tags ${tag[*]}--name resource-group-name

正如@socowi 所建议的那样,我还尝试在命令中的变量周围加上引号,但这会导致以下错误结果:一个标签而不是两个标签:

az group update --tags "$tag" --name resource-group-name

{
  "id": "/subscriptions/1e42c44c-bc55-4b8a-b35e-de1dfbcfe481/resourceGroups/resource-group-name",
  "location": "westeurope",
  "managedBy": null,
  "name": "resource-group-name",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": {
    "owner": "Firstname Lastname application=cool-name"
  }
}

有人知道怎么解决吗?

【问题讨论】:

  • 长话短说,写--tags "$tag"thisthisthis 的重复项。
  • 感谢@Socowi,但我忘了在我的原始帖子中提到我已经尝试过了,但没有任何运气。将相应地更新帖子。
  • 您找到了令人满意的解决方案吗?在这里尝试了无数种组合,但即使是公认的答案也不适合我
  • 我怀疑解决方案(至少在 bash 下)是用 \ 替换标记值中的空格(用斜杠转义的空格),但祝你好运找到一种方法来使它在已经有多个引用和转义语法与字符串混淆的脚本。

标签: bash azure tagging azure-cli azure-resource-group


【解决方案1】:

将您的标签定义为

tags=("owner=Firstname Lastname" "application=cool-name")

然后使用

--tags "${tags[@]}"

【讨论】:

    【解决方案2】:

    我发现了以下作品。它要求已经创建了一个资源组。

    我使用了以下模板:

    {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "resourceName": {
          "type": "string",
          "metadata": {
            "description": "Specifies the name of the resource"
          }
        },
        "location": {
          "type": "string",
          "defaultValue": "[resourceGroup().location]",
          "metadata": {
            "description": "Location for the resources."
          }
        },
        "resourceTags": {
          "type": "object",
          "defaultValue": {
            "Cost Center": "Admin"
          }
        }
      },
      "resources": [
        {
          "apiVersion": "2019-06-01",
          "kind": "StorageV2",
          "location": "[parameters('location')]",
          "name": "[parameters('resourceName')]",
          "properties": {
            "supportsHttpsTrafficOnly": true
          },
          "sku": {
            "name": "Standard_LRS"
          },
          "type": "Microsoft.Storage/storageAccounts",
          "tags": "[parameters('resourceTags')]"
        }
      ]
    }
    

    在使用 Bash 的 Azure CLI 中,您可以将标记作为 JSON 对象传递。在以下示例中,带有位置的模板文件需要两个参数,resourceName 和标签,这是一个名为 resourceTags 的 ARM 对象:

    az deployment group create --name addstorage  --resource-group myResourceGroup \
    --template-file $templateFile \
    --parameters resourceName=abcdef45216 resourceTags='{"owner":"bruce","Cost Cen":"2345-324"}'
    

    如果要将其作为环境变量传递,请使用:

    tags='{"owner":"bruce","Cost Center":"2345-324"}'
    az deployment group create --name addstorage  --resource-group myResourceGroup \
    --template-file $templateFile \
    --parameters resourceName=abcdef4556 resourceTags="$tags"
    
    

    $tags 必须用双引号括起来。 (您正在传递一个 JSON 对象字符串)

    将标签传递到 Azure DevOps 管道时,JSON 字符串也有效。见https://github.com/MicrosoftDocs/azure-devops-docs/issues/9051

    【讨论】:

      【解决方案3】:

      首先,像这样构建您的字符串,并为所有键/值加双引号,以防其中任何一个出现空格:(抱歉,这只是 PoSH 示例)

      [string] $tags = [string]::Empty;
      97..99 |% {
        $tags += "&`"$([char]$_)`"=`"$($_)`"";
      }
      

      这个结果是一个字符串"&"a"="97"&"b"="98"&"c"="99"

      现在使用基本字符串类的 split 函数将它作为字符串数组传递,这会产生一个 4 元素数组,第一个元素是空白的。 CLI 命令忽略第一个空元素。这里我设置了一个存储账户的标签。

      $tag='application=coolapp&owner="FirstName LastName"&"business Unit"="Human Resources"'
      az resource tag -g rg -n someResource --resource-type Microsoft.Storage/storageaccounts -tags $tag.split("&")
      

      当我想覆盖资源组部署的参数文件中提供的参数时,我也采用了这种方法。

      az group deployment create --resource-group $rgName --template-file $templatefile --parameters $parametersFile --parameters $($overrideParams.split("&"));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-09-23
        • 2013-06-29
        • 1970-01-01
        • 1970-01-01
        • 2015-03-23
        • 1970-01-01
        • 2012-09-09
        相关资源
        最近更新 更多