有效使用 Azure CLI
为清楚起见,将内联使用 Bash 脚本。 附录中列出了 Windows 批处理或 PowerShell 示例,可用于生成类似的示例。
输出格式(json、table 或 tsv)
json
格式是 CLI 的默认格式,旨在提供最全面的信息。 如果要使用其他格式,请使用--output
参数替代单个命令调用,或使用az configure
更新全局默认值。 请注意,JSON 格式保留双引号,因而一般不适合用于脚本编写。table
适用于获取重点信息的摘要,特别是对于列表命令。 如果不喜欢默认表格式的字段(或者没有默认格式),可以使用--output json
查看所有信息,或者利用--query
指定喜欢的格式。az vm show -g my_rg -n my_vm --query "{name: name, os:storageProfile.imageReference.offer}" -otable Name Os ------ ------------ my_vm UbuntuServer
tsv
适用于简洁的输出和编写脚本。 tsv 将去除 JSON 格式保留的双引号。 要为 TSV 指定所需的格式,请使用--query
参数。export vm_ids=$(az vm list -d -g my_rg --query "[?powerState=='VM running'].id" -o tsv) az vm stop --ids $vm_ids
将值从一个命令传递到另一个命令
如果将多次使用某个值,请将该值分配给变量。 请注意以下示例中
-o tsv
的用法:running_vm_ids=$(az vm list -d -g my_rg --query "[?powerState=='VM running'].id" -o tsv)
如果某个值只使用一次,请考虑使用管道:
az vm list --query "[?powerState=='VM running'].name" | grep my_vm
对于列表,请考虑以下建议:
如需加强对结果的控制,请使用“for”循环:
#!/usr/bin/env bash for vm in $(az vm list -d -g my_rg --query "[?powerState=='VM running'].id" -o tsv); do echo stopping $vm az vm stop --ids $vm if [ $? -ne 0 ]; then echo "Failed to stop $vm" exit 1 fi echo $vm stopped done
或者,使用
xargs
,并考虑使用-P
标志来并行运行操作以提高性能:az vm list -d -g my_rg --query "[?powerState=='VM stopped'].id" -o tsv | xargs -I {} -P 10 az vm start --ids "{}"
最后,Azure CLI 具有内置支持,可并行处理具有多个
--ids
的命令,以实现 xargs 的相同效果。 请注意,@-
用于从管道获取值:az vm list -d -g my_rg --query "[?powerState=='VM stopped'].id" -o tsv | az vm start --ids @-
异步操作
许多命令和组都会在其长时间运行的操作以及专用 wait
命令中公开 --no-wait
标志。 它们非常适用于特定方案:
在不依赖清理来执行某些后续操作(例如删除资源组)的情况下清理资源:
az group delete -n my_rg --no-wait
需要并行创建多个独立资源。 这类似于创建并联接线程:
az vm create -g my_rg -n vm1 --image centos --no-wait az vm create -g my_rg -n vm2 --image centos --no-wait subscription=$(az account show --query "id" -otsv) vm1_id="/subscriptions/$subscription/resourceGroups/my_rg/providers/Microsoft.Compute/virtualMachines/vm1" vm2_id="/subscriptions/$subscription/resourceGroups/my_rg/providers/Microsoft.Compute/virtualMachines/vm2" az vm wait --created --ids $vm1_id $vm2_id
泛型更新参数
CLI 中的大多数更新命令都具有三个泛型参数:--add
、--set
和 --remove
。 这些参数功能强大,但通常不如更新命令中通常使用的强类型参数方便。 CLI 为最常见的方案提供了强类型参数,以便于使用,但如果未列出你要设置的属性,泛型更新参数通常会提供一个路径来解除阻止,而无需等待新发布。
- 泛型更新语法并不是最便于使用的,因此请多一些耐心。
- 验证更新命令是否公开了
Generic Update Arguments
组。 如果没有,将需要提出问题,但如果公开了,则可以使用它们来尝试你的方案。 - 在相关资源上使用
show
命令,确定应在泛型参数中提供的路径。 例如,在尝试az vm update
之前,请运行az vm show
确定正确的路径。 通常,你将使用点语法来访问字典属性,并使用括号为列表编制索引。 - 请查看工作示例以开始使用。
az vm update -h
就提供了几个不错的示例。 --set
和--add
采用<key1>=<value1> <key2>=<value2>
格式的键值对列表。 使用它们可构造有意义的有效负载。 如果语法消息过多,请考虑使用 JSON 字符串。 例如,将新的数据磁盘附加到 VM:az vm update -g my_rg -n my_vm --add storageProfile.dataDisks "{\"createOption\": \"Attach\", \"managedDisk\": {\"id\": \"/subscriptions/0b1f6471-1bf0-4dda-aec3-cb9272f09590/resourceGroups/yg/providers/Microsoft.Compute/disks/yg-disk\"}, \"lun\": 1}"
- 你可能会发现,利用 CLI 的
@{file}
约定将 JSON 放入文件并进行加载会更有用。 这将上面的命令简化为:az vm update -g my_rg -n my_vm --add storageProfile.dataDisks @~/my_disk.json
通用资源命令 - az resource
在某些情况下,你感兴趣的服务可能没有 CLI 命令覆盖。 可以通过 az resource create/show/list/delete/update/invoke-action
命令来使用这些资源。 以下是一些建议:
- 如果仅涉及
create/update
,请考虑使用az group deployment create
。 利用 Azure 快速入门模板来获取工作示例。 - 有关请求有效负载、URL 和 API 版本,请查看 REST API 引用。 例如,查看社区对如何创建 AppInsights 的评论。
REST API 命令 - az rest
如果泛型更新参数和 az resource
都不能满足你的需要,则可以使用 az rest
命令调用 REST API。 它使用登录凭据自动进行身份验证,并设置标头 Content-Type: application/json
。
这对于调用 Microsoft Graph API 非常有用,CLI 命令当前不支持此 API (#12946)。
例如,为了更新应用程序的 redirectUris
,我们使用以下命令调用更新应用程序 REST API:
# Line breaks for legibility only
# Get the application
az rest --method GET
--uri 'https://graph.microsoft.com/v1.0/applications/b4e4d2ab-e2cb-45d5-a31a-98eb3f364001'
# Update `redirectUris` for `web` property
az rest --method PATCH
--uri 'https://graph.microsoft.com/v1.0/applications/b4e4d2ab-e2cb-45d5-a31a-98eb3f364001'
--body '{"web":{"redirectUris":["https://myapp.com"]}}'
将 --uri-parameters
用于 OData 格式的请求时,请确保在不同的环境中对 $
进行转义:在 Bash
中,将 $
转义为 \$
,在 PowerShell
中,将 $
转义为 `$
引号问题
这之所以成为一个问题,是因为当命令行界面(Bash、Zsh、Windows 命令提示符和 PowerShell 等)分析 CLI 命令时,它将解释引号和空格。 如果不确定 shell 的用法,请始终参阅文档:
- Bash:引号
- PowerShell:关于引号规则
- 由于 PowerShell 的已知问题 #1995,因此需要应用一些额外的转义规则。 有关详细信息,请参阅 PowerShell 引号问题。
- Windows 命令提示符:操作说明:在 Windows 命令行处对字符、分隔符和引号进行转义
为了避免出现意外结果,此处提供了一些建议:
如果值包含空格,则必须将其括在引号中。
在 Bash 或 Windows PowerShell 中,将解释单引号和双引号,而在 Windows 命令提示符中,仅处理双引号,这意味着单引号将被解释为值的一部分。
如果命令仅在 Bash(或 Zsh)上运行,则使用单引号可以保留其中的内容。 提供内联 JSON 时,这可能非常有用。 例如,以下命令可在 bash 中正常工作:
'{"foo": "bar"}'
如果命令在 Windows 命令提示符上运行,则必须使用双引号。 如果值包含双引号,则必须对其进行转义:
"i like to use \" a lot"
。 与上面的命令等效的命令提示符为:"{\"foo\": \"bar\"}"
将计算 bash 中包含在双引号内的导出变量。 如果未得到想要的结果,请再次使用
\
对其进行转义(如"\$var"
),或者使用单引号'$var'
。一些 CLI 参数(包括泛型更新参数)采用空格分隔的值列表,如
<key1>=<value1> <key2>=<value2>
。 由于键名和值可以采用任意字符串,其中可能包含空格,因此必须使用引号。 包装对,而不是单个键或值。 因此"my name"=john
是错误的。 请改用"my name=john"
。 例如:az webapp config appsettings set -g my_rg -n my_web --settings "client id=id1" "my name=john"
使用 CLI 的
@<file>
约定从文件加载,从而绕过 shell 的解释机制:az ad app create --display-name my-native --native-app --required-resource-accesses @manifest.json
当 CLI 参数表示它接受以空格分隔的列表时,以下是接受的格式:
--arg foo bar
:没问题。 未加引号的空格分隔列表--arg "foo" "bar"
:正常:加引号的空格分隔列表--arg "foo bar"
:错误。 这是一个包含空格的字符串,而不是以空格分隔的列表。
在 PowerShell 中运行 Azure CLI 命令时,当参数包含 PowerShell 的特殊字符(例如
@
)时,将发生分析错误。 要解决此问题,可以通过在特殊字符之前添加`
对其进行转义,或者可以在参数两边加单引号或双引号'
/"
。 例如,az group deployment create --parameters @parameters.json
在 PowerShell 中不起作用,因为@
被分析为展开符号。 要解决此问题,可以将参数更改为`@parameters.json
或'@parameters.json'
。将
--query
与命令一起使用时,需要在 shell 中对 JMESPath 的某些字符进行转义。 例如,在 Bash 中执行以下代码:# Wrong, as the dash needs to be quoted in a JMESPath query $ az version --query azure-cli az version: error: argument --query: invalid jmespath_type value: 'azure-cli' # Wrong, as the dash needs to be quoted in a JMESPath query, but quotes are interpreted by Bash $ az version --query "azure-cli" az version: error: argument --query: invalid jmespath_type value: 'azure-cli' # Correct $ az version --query '"azure-cli"' "2.5.1" $ az version --query \"azure-cli\" "2.5.1" $ az version --query "\"azure-cli\"" "2.5.1"
在命令提示符中:
> az version --query "\"azure-cli\"" "2.5.1" > az version --query \"azure-cli\" "2.5.1"
在 PowerShell 中(需要额外转义):
> az version --query '\"azure-cli\"' "2.5.1" > az version --query "\`"azure-cli\`"" "2.5.1" > az version --query "\""azure-cli\""" "2.5.1" > az --% version --query "\"azure-cli\"" "2.5.1" > az --% version --query \"azure-cli\" "2.5.1"
解决引号问题的最佳方法是运行带有
--debug
标志的命令。 它显示了 CLI 在 Python 语法中接收到的实际参数。 例如,在 Bash 中执行以下代码:# Wrong, as quotes and spaces are interpreted by Bash $ az {"key": "value"} --debug Command arguments: ['{key:', 'value}', '--debug'] # Wrong, as quotes are interpreted by Bash $ az {"key":"value"} --debug Command arguments: ['{key:value}', '--debug'] # Correct $ az '{"key":"value"}' --debug Command arguments: ['{"key":"value"}', '--debug'] # Correct $ az "{\"key\":\"value\"}" --debug Command arguments: ['{"key":"value"}', '--debug']
在代理后面工作
代理在公司网络背后很常见,或者由 Fiddler、mitmproxy 等跟踪工具引入。如果代理使用自签名证书,则 CLI 使用的 Python 请求库将引发 SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",)
。 可以通过两种方法来处理此错误:
将环境变量
REQUESTS_CA_BUNDLE
设置为 PEM 格式的 CA 捆绑证书文件的路径。 如果你经常在公司代理后面使用 CLI,则建议这样做。 在 Windows 上,CLI 使用的默认 CA 捆绑位于C:\Program Files (x86)\Microsoft SDKs\Azure\CLI2\Lib\site-packages\certifi\cacert.pem
,在 Linux 上,该捆绑位于/opt/az/lib/python3.6/site-packages/certifi/cacert.pem
。 可以将代理服务器的证书追加到此文件,或将内容复制到另一个证书文件,然后将REQUESTS_CA_BUNDLE
设置为该文件。 例如:<Original cacert.pem> -----BEGIN CERTIFICATE----- <Your proxy's certificate here> -----END CERTIFICATE-----
一个常见的问题为是否应该设置
HTTP_PROXY
或HTTPS_PROXY
环境变量,答案是视情况而定。 对于 Windows 上的 Fiddler,默认情况下,它在启动时充当系统代理,你无需进行任何设置。 如果该选项处于关闭状态或使用其他无法用作系统代理的工具,则应设置它们。 由于来自 CLI 的几乎所有流量都基于 SSL,因此仅应设置HTTPS_PROXY
。 如果你不确定,那就设置它们,但请记住在代理关闭后取消设置。 对于 fiddler,默认值为http://localhost:8888
。某些代理要求进行身份验证,因此
HTTP_PROXY
或HTTPS_PROXY
环境变量的格式应包含身份验证,例如HTTPS_PROXY="https://username:password@proxy-server:port"
。 底层 python 库需要此信息。 有关详细信息,请参阅如何为 Azure 库配置代理有关其他详细信息,请查看 Stefan 的博客。
通过设置环境变量
AZURE_CLI_DISABLE_CONNECTION_VERIFICATION=1
,禁用跨 Azure CLI 的证书检查。 这并不安全,但在短期内效果很好,例如捕获特定命令的网络跟踪并在完成后立即将其关闭。 由于潜在的 SDK 限制,这可能不适用于某些数据平面命令。
并发生成
如果在生成计算机上使用 az,并且可以并行运行多个作业,则存在登录令牌在两个生成作业之间共享的风险,因为这些作业以同一 OS 用户身份运行。 为避免此类混淆,请将 AZURE_CONFIG_DIR 设置为应存储登录令牌的目录。 它可以是随机创建的文件夹,也可以只是 jenkins 工作区的名称,例如 AZURE_CONFIG_DIR=.
附录
Windows 批处理脚本,用于保存到变量并在以后使用
ECHO OFF
SETLOCAL
FOR /F "tokens=* USEBACKQ" %%F IN (`az vm list -d -g my_rg --query "[?powerState=='VM running'].id" -o tsv`) DO (
SET "vm_ids=%%F %vm_ids%" :: construct the id list
)
az vm stop --ids %vm_ids% :: CLI stops all VMs in parallel
Windows PowerShell 脚本,用于保存到变量并在以后使用
$vm_ids=(az vm list -d -g my_rg --query "[?powerState=='VM running'].id" -o tsv)
az vm stop --ids $vm_ids # CLI stops all VMs in parallel
Windows 批处理脚本,用于循环访问列表
ECHO OFF
SETLOCAL
FOR /F "tokens=* USEBACKQ" %%F IN (`az vm list -d -g my_rg --query "[?powerState=='VM running'].id" -o tsv`) DO (
ECHO Stopping %%F
az vm stop --ids %%F
)
Windows PowerShell 脚本,用于循环访问列表
$vm_ids=(az vm list -d -g my_rg --query "[?powerState=='VM running'].id" -o tsv)
foreach ($vm_id in $vm_ids) {
Write-Output "Stopping $vm_id"
az vm stop --ids $vm_id
}
CLI 环境变量
环境变量 | 描述 |
---|---|
AZURE_CONFIG_DIR | 用于配置文件、日志和遥测的全局配置目录。 如果未指定,则默认为 ~/.azure 。 |
AZURE_EXTENSION_DIR | 扩展的安装目录。 如果未指定,则默认为全局配置目录中的 cliextensions 目录。 |