Azure CLI 是一种通过 Azure CLI 参考命令管理 Azure 资源的工具,该命令以 Bash 和 PowerShell 脚本语言运行。 但是,脚本语言之间的参数格式存在轻微的语法差异,这可能会导致意外结果。 本文旨在帮助你解决使用 PowerShell 脚本语言时的 Azure CLI 语法错误。
本文比较了使用以下脚本语言执行的 Azure CLI 命令的语法差异:
- 在 Linux 操作系统中,使用 Azure Cloud Shell 运行的 Bash。
- 在 Linux 操作系统中使用 Azure Cloud Shell 运行的 PowerShell。
- 使用 PowerShell 5 终端在 Windows 11 中运行的 Windows PowerShell。
- 使用 PowerShell 7 终端在 Windows 11 中运行的 PowerShell。
如果你不熟悉 CLI, 则工具 与 脚本语言 之间的差异可能会令人困惑。 如何选择正确的命令行工具 可提供很好的比较。
先决条件
重要
如果 Azure CLI 脚本生成错误, 请考虑你正在使用的脚本语言如何分析 Azure CLI 命令语法。
在 Azure CLI 参数中传递空格
在 Azure CLI 中,需要传递包含空格的参数值时,不同操作系统和脚本语言之间的引用方式存在差异。 在此示例中,使用 az storage account list 并将输出列重命名为包含空格的词。
在此示例中,请注意用单引号('...'
)括起来并嵌入双引号("..."
)的情况。
此示例也适用于 Linux 中的 PowerShell。
az storage account list --query '[].{"SA Name":name, "Primary endpoint":primaryEndpoints.blob}' --output table
如果要添加筛选器,语法将更改。 请注意此示例如何将参数值包装 --query
在双引号 ("..."
) 中,并使用反斜杠 (\
) 转义字符。 此脚本不会在 PowerShell 中运行。
az storage account list --query "[?creationTime >='2024-02-01'].{\"SA Name\":name,\"Primary endpoint\":primaryEndpoints.blob}" --output table
如果刚刚尝试以 PowerShell 脚本语言运行筛选器语法,则会收到错误消息 argument --query: invalid jmespath_type value: "[?creationTime >=..."
。 但是,在 Linux 环境中的 Bash 中,输出如下所示:
SA Name Primary Endpoint
----------- -----------------
msdocssa00000000 https://msdocssa000000000.blob.core.windows.net/
在包含查询字符串的 URL 中传递参数
URL 中的问号指示 URL 的末尾和查询字符串的开头。 以下是在教程学习使用 Azure CLI中打开步骤 3 的示例:
/cli/azure/account?view=azure-cli-2020-09-01-hybrid
。
?view=azure-cli-2020-09-01-hybrid
得出了所需版本的 Azure CLI 参考内容。
使用 PowerShell 脚本语言执行 Azure CLI 命令时,PowerShell 允许问号成为变量名称的一部分。 这可能会在 Azure CLI 参数值中创建混淆。
下面是 “使用 Azure REST API ”一文中的一个示例:
请注意 Bash 中 $containerRegistryName?api-version
是如何无错误地连接在一起的。
# Script for a Bash scripting language
# Variable block
let "randomIdentifier=$RANDOM*$RANDOM"
subscriptionId="00000000-0000-0000-0000-000000000000"
resourceGroup="msdocs-app-rg$randomIdentifier"
containerRegistryName="msdocscr$randomIdentifier"
# prior to this GET example, the resource group and container registry were created in the article.
az rest --method get --url https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.ContainerRegistry/registries/$containerRegistryName?api-version=2023-01-01-preview
传递包含与号的参数
如果需要在参数值中传递安和号,请注意 PowerShell 会解释与号(&
) 符号。 您可以通过使用--debug
参数看到这一情况:
az "a&b" --debug
# output
'a' is misspelled or not recognized by the system.
'b' is not recognized as an internal or external command
但是,如果使用此相同的测试将标记添加到资源组,则标记值中的符号&不会导致错误。
az group create --___location eastus2 --name "msdocs-rg-test"
az group update --name "msdocs-rg-test" --tags "company name=Contoso & Sons"
# output
{
"id": "/subscriptions/3618afcd-ea52-4ceb-bb46-53bb962d4e0b/resourceGroups/msdocs-rg-test",
"___location": "eastus2",
"managedBy": null,
"name": "msdocs-rg-test",
"properties": {
"provisioningState": "Succeeded"
},
"tags": {
"company name": "Contoso & Sons"
},
"type": "Microsoft.Resources/resourceGroups"
}
如果在某种情况下,参数值中的符号"&"导致错误,以下是一些解决方案:
# When quoted by single quotes ('), double quotes (") are preserved by PowerShell and sent
# to Command Prompt, so that ampersand (&) is treated as a literal character
> az '"a&b"' --debug
Command arguments: ['a&b', '--debug']
# Escape double quotes (") with backticks (`) as required by PowerShell
> az "`"a&b`"" --debug
Command arguments: ['a&b', '--debug']
# Escape double quotes (") by repeating them
> az """a&b""" --debug
Command arguments: ['a&b', '--debug']
# With a whitespace in the argument, double quotes (") are preserved by PowerShell and
# sent to Command Prompt
> az "a&b " --debug
Command arguments: ['a&b ', '--debug']
# Use --% to stop PowerShell from parsing the argument
> az --% "a&b" --debug
Command arguments: ['a&b', '--debug']
传递包含 at (@
) 符号的参数
PowerShell 有特殊字符,例如 @ 符号(@
),它是 PowerShell 中的 展开运算符。 在特殊字符之前添加反引号 `
以对其进行转义。 还可以将值括在单引号'
或双"
引号中。
以下三个示例将在 PowerShell 中工作:
- parameterName `@parameters.json
- parameterName '@parameters.json'
- parameterName“@parameters.json”
此示例在 PowerShell 中不起作用:
- parameterName @parameters.json
下面是命令中的 az ad app create
另一个示例:请注意 PowerShell 脚本语言中所需的 JSON 文件名的双引号("..."
)。
# Script for a PowerShell scripting language
az ad app create --display-name myTestAppName `
--is-fallback-public-client `
--required-resource-accesses "@manifest.json"
传递包含 JSON 的参数
对于 JSON 字符串等复杂参数,最佳做法是使用 Azure CLI 的 @<file>
约定从文件加载,以绕过 shell 的解释。 有关 Bash、PowerShell 和 Cmd.exe的 JSON 语法示例,请参阅 脚本语言 - JSON 字符串之间的引用差异。
传递包含 key:value 对的参数
某些 Azure CLI 参数值(如 Azure 资源标记)需要键:值对。 如果key
或value
中包含空格或特殊字符,Bash 和 PowerShell 的语法不一定总相同。
有关 Bash、PowerShell 和 Cmd 的语法示例,请参阅创建标记以练习引用差异,在学习使用 Azure CLI教程中。 本教程步骤提供了以下键值对场景的示例:
- 空间
- 空值
- 特殊字符
- 变量
停止解析符号
PowerShell 3.0 中引入的停止分析符号(--%
)指示 PowerShell 不要将输入解释为 PowerShell 命令或表达式。 遇到停止分析符号时,PowerShell 会将行中的剩余字符视为文本。
az --% vm create --name xxx
PowerShell 中 Azure CLI 的错误处理
可以在 PowerShell 中运行 Azure CLI 命令,如 选择正确的 Azure 命令行工具中所述。 如果这样做,请确保了解 PowerShell 中的 Azure CLI 错误处理。 具体而言,Azure CLI 不会创建异常供 PowerShell 捕获。
替代方法是使用 $?
自动变量。 此变量包含最新命令的状态。 如果上一个命令失败, $?
则值为 $False
. 有关详细信息,请参阅 about_Automatic_Variables。
以下示例演示此自动变量如何适用于错误处理:
# Script for a PowerShell scripting language
az group create --name MyResourceGroup
if ($? -eq $false) {
Write-Error "Error creating resource group."
}
命令 az
失败,因为它缺少所需的 --___location
参数。 条件语句判断 $?
为 false 并记录错误。
如果您想使用try
和catch
关键字,可以使用throw
为try
块创建一个用于捕获的异常:
# Script for a PowerShell scripting language
$ErrorActionPreference = "Stop"
try {
az group create --name MyResourceGroup
if ($? -eq $false) {
throw 'Group create failed.'
}
}
catch {
Write-Error "Error creating the resource group."
}
$ErrorActionPreference = "Continue"
默认情况下,PowerShell 只捕获终止错误。 本示例将 $ErrorActionPreference
全局变量设置为 Stop
这样 PowerShell 可以处理错误。
条件语句测试 $?
变量,以查看上一个命令是否失败。 如果是这样,那么关键字 throw
创建了一个供捕获的异常。 该 catch
块可用于编写错误消息或处理错误。
该示例还原 $ErrorActionPreference
到其默认值。
有关 PowerShell 错误处理的详细信息,请参阅 想要了解的关于异常的所有内容。
在 PowerShell 中启用 Tab 键补全功能
Tab 键自动补全,也称为“Azure CLI 补全器”,提供输入自动补全功能,以提供提示、便于探索并加速输入。 可以通过按 Tab 键将命令名称、命令组名称、参数和某些参数值自动插入到命令行中。
Tab 键补全功能在 Azure Cloud Shell 和大多数 Linux 发行版中默认启用。 从 Azure CLI 版本 2.49 开始,可以在 PowerShell 中为 Azure CLI 启用 Tab 补全功能。 执行以下步骤:
创建或编辑存储在变量
$PROFILE
中的配置文件。 最简单的方法是在 PowerShell 中运行notepad $PROFILE
。 有关详细信息,请参阅如何创建配置文件和配置文件和执行策略。将以下代码添加到 PowerShell 配置文件:
Register-ArgumentCompleter -Native -CommandName az -ScriptBlock { param($commandName, $wordToComplete, $cursorPosition) $completion_file = New-TemporaryFile $env:ARGCOMPLETE_USE_TEMPFILES = 1 $env:_ARGCOMPLETE_STDOUT_FILENAME = $completion_file $env:COMP_LINE = $wordToComplete $env:COMP_POINT = $cursorPosition $env:_ARGCOMPLETE = 1 $env:_ARGCOMPLETE_SUPPRESS_SPACE = 0 $env:_ARGCOMPLETE_IFS = "`n" $env:_ARGCOMPLETE_SHELL = 'powershell' az 2>&1 | Out-Null Get-Content $completion_file | Sort-Object | ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, "ParameterValue", $_) } Remove-Item $completion_file, Env:\_ARGCOMPLETE_STDOUT_FILENAME, Env:\ARGCOMPLETE_USE_TEMPFILES, Env:\COMP_LINE, Env:\COMP_POINT, Env:\_ARGCOMPLETE, Env:\_ARGCOMPLETE_SUPPRESS_SPACE, Env:\_ARGCOMPLETE_IFS, Env:\_ARGCOMPLETE_SHELL }
若要显示菜单中的所有可用选项,请将
Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete
添加到 PowerShell 配置文件。
另请参阅
- 有关 PowerShell 的引用问题的 Azure CLI 工程说明
- 在以下文章中比较 Bash、PowerShell 和 Cmd 的语法: