空格分隔值;如何提供包含空格的值

问题描述 投票:0回答:4

我正在创建一个 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"
  }
}

有人知道如何解决这个问题吗?

bash azure tagging azure-cli azure-resource-group
4个回答
8
投票

将您的标签定义为

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

然后使用

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

1
投票

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

我使用了以下模板:

{
  "$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


0
投票

首先,像这样构建字符串,并用双引号引用所有键/值,以防其中出现空格:(抱歉,这只是 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("&"));

0
投票

我使用以下 bash 脚本来标记订阅中的所有资源。 它对我们有用。

# set subscription before running script
tags=('App=Datawarehouse', '[email protected]', 'Cost Center=1234', 'Division=IT', 'Support Tier=0')
resourceIds=$(az resource list --query "[*].[id]" -o tsv)

for resourceId in $resourceIds
do
    
    az tag update --resource-id $resourceId --operation replace --tags "${tags[@]}"

done
© www.soinside.com 2019 - 2024. All rights reserved.