你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

了解 Bash、PowerShell 和 Cmd 之间的 Azure CLI 语法差异

可以在 Bash、PowerShell 和 Windows 命令行界面(Cmd)脚本语言中执行 Azure CLI 命令。 但是,编写脚本时存在细微的差异。 在本教程步骤中,了解如何为所有三种脚本语言创建第一个Azure 存储帐户和格式参数值。

先决条件

  • 已完成准备环境的先决条件。
  • 可以访问在资源组级别具有 contributor 或更高权限的资源组。

了解续行符

大多数 Azure CLI 文档都是使用 Azure Cloud Shell 在 Bash 中编写和测试的。 复制 Azure CLI 语法时要记住的第一件事是验证所选脚本语言的行延续字符,因为它们不可互换。

脚本语言 续行符
Bash 反斜杠 (\)
PowerShell 反引号 (`)
Cmd 转义符 (^)

提示

Azure CLI 代码块右上角的“复制”按钮按照设计会删除反斜杠 (\) 和反引号 (`)。 如果要复制有格式的代码块,请使用键盘或鼠标选择并复制示例。

了解使用变量时的语法差异

使用变量的语法在脚本语言之间略有不同。 对比如下:

用例 Bash PowerShell Cmd
创建变量 variableName=varValue $variableName="varValue" set variableName=varValue
使用变量作为参数值 variableName $variableName %variableName%
--query 参数中使用变量 '$variableName' '$variableName' '$variableName'

有多种不同的方法可将变量信息返回到控制台屏幕,但 echo 在大多数情况下均有效。 对比如下:

  • Bash:echo $varResourceGroup
  • PowerShell:echo $varResourceGroup
  • Cmd:echo %varResourceGroup%

在第三步填充脚本中使用的变量中,你将深入讨探变量语法的示例。

了解脚本语言之间的差异

每个 Azure CLI 参数都是一个字符串。 但是,每个脚本语言都有自己的规则来处理单引号、空格和参数值。

字符串值 Azure CLI PowerShell Cmd
文本 ‘text’ 或“text” ‘text’ 或“text” "text"
Number \`50\` ``50`` `50`
布尔 \`true\` ``false`` 'true'
日期 '2021-11-15' '2021-11-15' '2021-11-15'
JSON '{"key":"value"}' 或 "{"key":"value"}" '{“key”: “value”}' 或 “{'”key'“: '”value'“}” 或 “{”“key”: “”value“”}” "{"key":"value"}"

许多 Azure CLI 参数都接受空格分隔值列表。 这会影响引用。

  • 未加引号的空格分隔列表:--parameterName firstValue secondValue
  • 加引号的空格分隔列表:--parameterName "firstValue" "secondValue"
  • 包含空格的值:--parameterName "value1a value1b" "value2a value2b" "value3"

如果不确定如何通过脚本语言评估字符串,请将字符串的值返回到控制台或使用--debug调试 Azure CLI 参考命令中所述

运用所学内容创建一个存储帐户

本教程步骤的其余部分演示了 Azure CLI 命令中的引用规则,并使用在为 Azure CLI 准备环境中创建的资源组。 将 <msdocs-tutorial-rg-00000000> 替换为你的资源组名称。

创建要在本教程中使用的 Azure 存储帐户。 此示例将随机 ID 分配给存储帐户名称,但如果要使用其他名称,请参阅存储帐户概述了解存储帐户名称规则。

重要

必须先在订阅中注册资源提供程序, Microsoft.Storage 然后才能创建存储帐户。 若要了解如何注册资源类型,请参阅 “注册资源提供程序”。

下一个脚本示例演示了以下脚本的特定于语言的语法:

  • 续行符
  • 变量使用
  • 随机标识符
  • echo 命令
# Variable block
let "randomIdentifier=$RANDOM*$RANDOM"
location="eastus"
resourceGroup="<msdocs-tutorial-rg-00000000>"
storageAccount="msdocssa$randomIdentifier"

# Create a storage account.
echo "Creating storage account $storageAccount in resource group $resourceGroup"
az storage account create --name $storageAccount \
                          --resource-group $resourceGroup \
                          --location $location \
                          --sku Standard_RAGRS \
                          --kind StorageV2 \
                          --output json

注意

是否刚刚收到“找不到订阅”错误? 如果未在活动订阅中注册, Microsoft.Storage 则会发生此错误。 若要注册资源提供程序,请参阅 Azure 资源提供程序和类型

创建新的存储帐户时,Azure CLI 将返回 100 多行 JSON 作为输出。 为简洁起见,以下 JSON 字典输出已省略了字段。

{
"accessTier": "Hot",
"allowBlobPublicAccess": false,
"creationTime": "yyyy-mm-ddT19:14:26.962501+00:00",
"enableHttpsTrafficOnly": true,
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/ msdocs-tutorial-rg-00000000/providers/Microsoft.Storage/storageAccounts/msdocssa00000000",
"keyCreationTime": {
  "key1": "yyyy-mm-ddT19:14:27.103127+00:00",
  "key2": "yyyy-mm-ddT19:14:27.103127+00:00"
},
"kind": "StorageV2",
"location": "eastus",
"name": "msdocssa00000000",
"primaryEndpoints": {
  "blob": "https://msdocssa00000000.blob.core.windows.net/"
},
"primaryLocation": "eastus",
"provisioningState": "Succeeded",
"resourceGroup": "msdocs-tutorial-rg-00000000",
"sku": {
  "name": "Standard_RAGRS",
  "tier": "Standard"
},
"statusOfPrimary": "available",
"statusOfSecondary": "available",
"tags": {},
"type": "Microsoft.Storage/storageAccounts"
}

创建标记以练习引用差异

使用 az storage account update,添加标记来帮助识别存储帐户并了解引用差异。 这些脚本示例演示了以下脚本特定于语言的语法:

  • 包含空格的值
  • 引用空格
  • 转义特殊字符
  • 使用变量

--tags 参数接受键:值对的空格分隔列表。 将 <msdocs-tutorial-rg-00000000> 替换为资源组的名称,并将 <msdocssa00000000> 替换为 Azure 存储帐户的名称。

# Create new tags. This syntax works with or without quotes around each key-value pair.
az storage account update --name <msdocssa00000000> \
                          --resource-group <msdocs-tutorial-rg-00000000> \
                          --tags Team=t1 Environment=e1

# Create new tags containing spaces. You must use quotes.
az storage account update --name <msdocssa00000000> \
                          --resource-group <msdocs-tutorial-rg-00000000> \
                          --tags "Floor number=f1" "Cost center=cc1"

# Create a new tag with an empty value.
az storage account update --name <msdocssa00000000> \
                          --resource-group <msdocs-tutorial-rg-00000000> \
                          --tags "Department="''""

# Create a new tag containing special characters resulting in "Path": "$G:\\myPath".
az storage account update --name <msdocssa00000000> \
                          --resource-group <msdocs-tutorial-rg-00000000> \
                          --tags "Path=\$G:\myPath"

# Create a tag from a variable.
newTag="tag1=tag value with spaces"
az storage account update --name <msdocssa00000000> \
                          --resource-group <msdocs-tutorial-rg-00000000> \
                          --tags "$newTag"

如果不想在完成本教程步骤时覆盖以前的标记,请使用 az tag update 命令将 --operation 参数设置为 merge

# Get the resource ID of your storage account.
saID=$(az resource show --resource-group <msdocs-tutorial-rg-00000000> \
                        --name <msdocssa00000000> \
                        --resource-type Microsoft.Storage/storageAccounts \
                        --query "id" \
                        --output tsv)

echo My storage account ID is $saID

# Append new tags.
az tag update --resource-id $saID \
              --operation merge \
              --tags <tagName>=<tagValue>

# Get a list of all tags.
az tag list --resource-id $saID

比较更多特定于语言的脚本

更深入地了解这些脚本差异。 这些示例演示了以下内容的引用差异:

  • 将 JSON 字符串作为参数值传递
  • 使用 --query 参数筛选结果
    • 数字
    • 布尔值
    • 日期

包含 JSON 字符串的参数示例。 此脚本供将来参考,因为我们未在本教程中使用 az rest

az rest --method patch \
        --url https://management.azure.com/subscriptions/<mySubscriptionID>/resourceGroups/<myResourceGroup>/providers/Microsoft.HybridCompute/machines/<machineName>?api-version=yyyy-mm-dd-preview \
        --resource https://management.azure.com/ \
        --headers Content-Type=application/json \
        --body '{"properties": {"agentUpgrade": {"enableAutomaticUpgrade": false}}}'

数值筛选示例。 除非当前订阅中有一个 VM,否则此示例供将来参考。

az vm list --resource-group <myResourceGroup> \
           --query "[?storageProfile.osDisk.diskSizeGb >=\`50\`].{Name:name, admin:osProfile.adminUsername, DiskSize:storageProfile.osDisk.diskSizeGb}" \
           --output table

使用本教程中创建的存储帐户筛选布尔值的示例。

az storage account list --resource-group <msdocs-tutorial-rg-00000000> \
    --query "[?allowBlobPublicAccess == \`true\`].id"

使用本教程中创建的存储帐户筛选日期的示例。

# include time
az storage account list --resource-group <msdocs-tutorial-rg-00000000> \
    --query "[?creationTime >='2021-11-15T19:14:27.103127+00:00'].{saName:name, saID: id, sku: sku.name}"

# exclude time
az storage account list --resource-group <msdocs-tutorial-rg-00000000> \
    --query "[?creationTime >='2021-11-15'].{saName:name, saID: id, sku: sku.name}"

# subtract days and use a variable
saDate=$(date +%F -d "-30days")
az storage account list --resource-group <msdocs-tutorial-rg-00000000> \
    --query "[?creationTime >='$saDate'].{saName:name, saID: id, sku: sku.name}"

调试 Azure CLI 参考命令

使用 --debug 参数

Azure CLI 提供可用于任何命令的 --debug 参数。 调试输出很广泛,但它为你提供了包括以下内容的信息:

  • 由脚本语言解释的命令参数(参数值)
  • 日志文件的位置
  • API 调用详细信息
  • 执行错误

如果在使用 Azure CLI 命令时遇到难以理解和更正执行错误, --debug 则查看 Azure CLI 正在执行的步骤的答案。

下面是创建存储帐户时调试输出的一小部分:

 cli.knack.cli: Command arguments: ['storage', 'account', 'create', '--name', 'msdocssa00000000', '--resource-group', 'msdocs-rg-test', '--location', 'eastus', '--sku', 'Standard_RAGRS', '--kind', 'StorageV2', '--output', 'json', '--debug']
 ...
 cli.azure.cli.core.sdk.policies: Request URL: 'https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Storage/checkNameAvailability?api-version=2023-01-01'
cli.azure.cli.core.sdk.policies: Request method: 'POST'
cli.azure.cli.core.sdk.policies: Request headers:
cli.azure.cli.core.sdk.policies:     'Content-Type': 'application/json'
cli.azure.cli.core.sdk.policies:     'Content-Length': '73'
cli.azure.cli.core.sdk.policies:     'Accept': 'application/json'
cli.azure.cli.core.sdk.policies:     'x-ms-client-request-id': '00000000-0000-0000-0000-000000000000'
cli.azure.cli.core.sdk.policies:     'CommandName': 'storage account create'
cli.azure.cli.core.sdk.policies:     'ParameterSetName': '--name --resource-group --location --sku --kind --output --debug'
cli.azure.cli.core.sdk.policies:     'User-Agent': 'AZURECLI/2.61.0 (DEB) azsdk-python-core/1.28.0 Python/3.11.8 (Linux-5.15.153.1-microsoft-standard-WSL2-x86_64-with-glibc2.35)'
cli.azure.cli.core.sdk.policies:     'Authorization': '*****'
cli.azure.cli.core.sdk.policies: Request body:
cli.azure.cli.core.sdk.policies: {"name": "msdocssa00000000", "type": "Microsoft.Storage/storageAccounts"}
urllib3.connectionpool: Starting new HTTPS connection (1): management.azure.com:443
urllib3.connectionpool: https://management.azure.com:443 "POST /subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Storage/checkNameAvailability?api-version=2023-01-01 HTTP/1.1" 200 22
cli.azure.cli.core.sdk.policies: Response status: 200
...

有关更多故障排除提示,请参阅 Azure CLI 故障排除。

使用 echo 命令

尽管 --debug 确切地告诉你 Azure CLI 解释的内容,但第二个选项是将表达式的值返回到控制台。 当验证填充脚本中使用的变量中详细介绍的 --query 的结果时,此方法非常有用。

strExpression='{"key":"value"}'
echo $strExpression
{"key":"value"}

疑难解答

下面是 Azure CLI 参考命令语法编写不正确时的常见错误:

  • “错误的请求...{something} 无效”可能是由空格、单引号或双引号或者缺少引号所致。

  • 当有额外的空间或引号时,将会显示“意外令牌...”。

  • “无效的 jmespath_type 值”错误通常是由于 --query 参数中的引用不正确。

  • 当通常由于串联或缺少转义字符而导致字符串的格式不正确时,用户将会收到“变量参考无效”。

  • “无法识别的参数”通常是由于续行符不正确所致。

  • 当缺少续行符时,将显示“一元运算符后缺少表达式”。

有关其他故障排除提示,请参阅 Azure CLI 命令故障排除

获取更多详细信息

想要更详细地了解本教程步骤中介绍的某项主题吗? 请使用下表中的链接了解详细信息。

主题 了解详细信息
脚本差异 引用脚本语言之间的差异
Bash 引用规则
PowerShell 引用规则
使用 PowerShell 脚本语言运行 Azure CLI 的注意事项
Windows 命令行提示
参数 在 Azure CLI 参数中使用引号
使用 JMESPath 查询命令输出中,查找 Bash、PowerShell 和 Cmd 的更多语法示例
故障排除 排查 Azure CLI 命令问题

下一步

了解如何为 Bash、PowerShell 和 Cmd 编写 Azure CLI 语法后,请继续执行下一步,了解如何将值提取到变量。