mar*_*ark 5 powershell arguments function function-call parameter-splatting
考虑以下简单函数:
function Write-HostIfNotVerbose()
{
if ($VerbosePreference -eq 'SilentlyContinue')
{
Write-Host @args
}
}
Run Code Online (Sandbox Code Playgroud)
而且效果很好:
现在我想让它成为一个高级函数,因为我希望它继承详细程度首选项:
function Write-HostIfNotVerbose([Parameter(ValueFromRemainingArguments)]$MyArgs)
{
if ($VerbosePreference -eq 'SilentlyContinue')
{
Write-Host @MyArgs
}
}
Run Code Online (Sandbox Code Playgroud)
但它不起作用:
让我抓狂的是,我无法确定第一个示例与第二$args个示例有何不同。$args
我知道@args默认情况下本机泼溅不适用于高级功能 - https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_splatting?view=powershell-7.2#notes
但我希望可以模拟,但也行不通。我的问题是 - 我尝试模拟它的方式有什么问题,以及是否可以在不显示所有参数的Write-Host情况下修复我的代码Write-HostIfNotVerbose
Santiago Squarzon 的有用答案包含一些出色的调查,揭示了背后隐藏的魔法@args,即使用自动变量进行喷溅,该变量仅在简单(非高级)函数中可用。$args
圣地亚哥的答案中的解决方案不仅复杂,而且也不完全健壮,因为它无法区分-ForegroundColor(参数名称)与恰好看起来像参数名称的'-ForegroundColor'参数值,但又与通过引用它。
@args魔法也有一个限制:它不能正确传递用显式值[switch]指定的参数,例如[1]-NoNewLine:$false强大的解决方案需要通过自动$PSBoundParameters变量展开,这反过来又要求包装函数本身也声明所有潜在的传递参数。
这样的包装函数称为代理函数,PowerShell SDK 通过 PowerShell SDK 方便地搭建此类函数,如本答案中所述。
在您的情况下,您必须按如下方式定义您的函数:
function Write-HostIfNotVerbose {
[CmdletBinding()]
param(
[Parameter(Position = 0, ValueFromPipeline, ValueFromRemainingArguments)]
[Alias('Msg', 'Message')]
$Object,
[switch] $NoNewline,
$Separator,
[System.ConsoleColor] $ForegroundColor,
[System.ConsoleColor] $BackgroundColor
)
begin {
$scriptCmd =
if ($VerbosePreference -eq 'SilentlyContinue') { { Write-Host @PSBoundParameters } }
else { { Out-Null } }
$steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
$steppablePipeline.Begin($PSCmdlet)
}
process {
$steppablePipeline.Process($_)
}
end {
$steppablePipeline.End()
}
}
Run Code Online (Sandbox Code Playgroud)
[1] 这样的参数总是作为两个参数传递,即作为参数名称-NoNewLine本身,后跟一个单独的参数$false。问题是,当原始参数被解析为 时$args,尚不知道它们将绑定到什么正式声明的参数。NoteProperty用于将元素标记为$args参数名称的标记不会保留有关后续参数是否与参数名称分隔的信息:,这对于[switch]参数来说是识别该参数属于 switch 所必需的。如果缺少此信息,则在展开过程中始终会传递两个单独的参数。
| 归档时间: |
|
| 查看次数: |
1074 次 |
| 最近记录: |