PowerShell 展开和哈希表值

最后更新: 2021-12-04 17:34:29 +0800 +0800
原文以英文撰写。您正在阅读AI翻译版本。

PowerShell 展开可以将哈希表或数组作为命名参数或位置参数传递。 它可以避免重复编写很长的参数列表,并将配置与命令调用分离。

展开 PowerShell 命令 #

在调用位置为哈希表变量添加 @ 前缀:

powershell
$request = @{
    Uri         = 'https://api.example.test/items'
    Method      = 'Get'
    Headers     = @{ Accept = 'application/json' }
    TimeoutSec  = 30
}

Invoke-RestMethod @request

哈希表键必须与参数名称匹配,包括受支持的别名。展开不会将任意字符串扩展为 shell 语法;PowerShell 会将生成的值作为具有类型的命令参数进行绑定。

PowerShell 7.1 及更高版本允许显式写出的命名参数覆盖展开哈希表中的同名参数。较早版本的 PowerShell 会报告重复绑定,因此跨版本脚本应在调用前更新哈希表副本:

powershell
$effective = $request.Clone()
$effective.TimeoutSec = 60
Invoke-RestMethod @effective

数组提供位置参数展开:

powershell
$copyArgs = @('source.txt', 'destination.txt')
Copy-Item @copyArgs

外部程序和插值 #

原生可执行文件接收的是字符串,而不是 PowerShell 参数绑定。插值字符串中的哈希表属性需要使用子表达式:

powershell
$config = @{
    AppId     = 'example-id'
    GroupCode = 'workers'
}

& $connector `
    "--app-id=$($config.AppId)" `
    "--group-code=$($config.GroupCode)"

"--app-id=$config.AppId" 会展开 $config,并将 .AppId 保留为字面文本,因此生成的值会以哈希表的字符串表示形式开头。$($config.AppId) 会在插值前计算成员访问。

当可执行文件具有可选标志时,应构建参数数组:

powershell
$arguments = @(
    '--server-mode=http'
    '--threads=10'
    "--app-id=$($config.AppId)"
)

& $connector @arguments
if ($LASTEXITCODE -ne 0) {
    throw "Connector failed with exit code $LASTEXITCODE"
}

调用运算符后的数组展开会为数组中的每个元素提供一个参数。避免构造单个命令字符串并将其传递给 Invoke-Expression;参数数组可以保留参数边界,并避免额外的解析步骤。

在 Windows 上,PowerShell 7.3 通过 $PSNativeCommandArgumentPassing 更改了原生参数传递方式;Standard、Windows 和 Legacy 模式控制引擎构造原生命令行的方式。类 Unix 系统会传递参数向量,而 Windows 程序可能应用自己的命令行解析器。与其手动序列化命令,不如针对受支持的 PowerShell 和可执行文件版本测试空字符串、嵌入式引号和末尾反斜杠。

评论

在 GitHub 上阅读或评论(发表评论需要登录)