我有一个脚本(我们称之为 caller.ps1),它调用另一个脚本 callee.ps1。在 caller.ps1 中,我想检查一些参数并将它们与其他一些参数一起传递给 callee.ps1
caller:
param (
[Parameter(Mandatory, ParameterSetName="ByA")][string]$a, // passthru
[Parameter(Mandatory, ParameterSetName="ByB")][string]$b, // passthru
// some more passthru parameters
[Parameter()][switch]$inspect, // inspect, then pass on
[Parameter()][switch]$consume // consume, do not pass on
)
callee:
param (
[Parameter(Mandatory, ParameterSetName="ByA")][string]$a,
[Parameter(Mandatory, ParameterSetName="ByB")][string]$b,
// some more parameters
[Parameter()][switch]$inspect
)
这里的最佳实践是什么?我已经尝试过 @args
但它看起来是空的。我想那是因为所有参数都绑定(bind)到名称?
由于我有两个参数集“ByA”和“ByB”,以及一堆开关参数,因此检查每个参数集并为被调用者编写一个新的参数列表会非常笨重。有没有一种优雅的方法来做到这一点?谢谢。
最佳答案
automatic variable $PSBoundParameters
在这种情况下非常有用,只要被调用者的参数名称具有相同的名称或具有 aliases ,它就允许您将相同的参数传递到下一个脚本 block 。与调用者的匹配。
使用2个脚本 block 进行演示,但逻辑与2个.ps1
文件完全相同。
$caller = {
param (
[Parameter(Mandatory, ParameterSetName="ByA")]
[string] $a,
[Parameter(Mandatory, ParameterSetName="ByB")]
[string] $b,
[Parameter()]
[switch] $inspect,
[Parameter()]
[switch] $consume
)
# remove the bound parameter before calling the next script
$null = $PSBoundParameters.Remove('consume')
# do whatever you need here with `$consume` then
# call the next script using the bounded parameters
& $callee @PSBoundParameters
}
$callee = {
param (
[Parameter(Mandatory, ParameterSetName="ByA")]
[string] $a,
[Parameter(Mandatory, ParameterSetName="ByB")]
[string] $b,
[Parameter()]
[switch] $inspect
)
$PSBoundParameters
}
& $caller -a 'hey there' -inspect -consume
至于为什么$args
不起作用,正如文档所述, $args
仅适用于未声明的参数,并且您的脚本正在使用 param
block (声明的参数),并且不允许未声明的参数,因为这些是advanced scriptblocks / functions从某种意义上说,由于 Parameter
attribute declarations .
一个简单的例子来直观地说明这意味着什么:
在此示例中,脚本 block 仅具有 2 个声明的参数和 3 个正在传递的参数,1 和 2 绑定(bind)到声明的参数,3 作为未声明的参数传递,因此绑定(bind)到 $args
:
# works fine, outputs 3
& {param($paramA, $paramB) $args } -paramA 1 -paramB 2 3
现在,如果我们尝试对高级脚本 block 执行相同的操作,我们将看到错误,因为它们不允许未声明的参数:
# Fails: A positional parameter cannot be found that accepts argument '3'.
& {[CmdletBinding()]param($paramA, $paramB) $args } -paramA 1 -paramB 2 3
关于Powershell:检查、使用和传递参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74710805/