2014-02-12 57 views
0

鉴于这种功能和调用:我可以抑制参数别名吗?

function Foo($bar) { 
    Write-Host "bar=$bar, other args = $args" 
} 

Foo -b baz -quux quuux 

PowerShell的将视-b参数作为别名$bar参数和打印

bar=baz, other args = -quux quuux 

我不希望它这样做!我的函数需要使用命名参数和任意附加参数;如果其中一个任意参数是-b,我不希望它分配到$bar。也就是我希望它能够打印:

bar=, other args = -b baz -quux quuux 

我可以抑制PowerShell的默认参数别名吗?

我使用PowerShell 2.0

回答

2

您可以通过引用它解释-b作为参数别名停止解析器:

function Foo($bar) { 
    Write-Host "bar=$bar, other args = $args" 
} 

Foo '-b' baz -quux quuux 

bar=-b, other args = baz -quux quuux 
+0

嗯。取而代之的是''-b''是一个位置参数。我想这是不可避免的。 – bacar

+0

除非你做了像Foo $ null'-b'baz -quux quuux – mjolinor

+0

我看到有'[CmdletBinding(PositionalBinding = $ false)]'](http://stackoverflow.com/a/17043457/37941)但是我无法在PS 2.0中工作 – bacar

2

AFAIK,你不能两者兼得。您可以使用展示您在此处看到的行为的“基本”功能,也可以使用带有命名参数的高级功能,这些参数将严格验证参数名称。

“任意参数”真的很难看,恕我直言,应该避免一些原因(其中一些涉及代码安全性 - 您最终可能会执行未知的任意代码?)。

使Foo为高级函数,并使您的“任意”参数为可选的Objects的集合。

function Foo { 
[cmdletBinding()] 
param (
    [Parameter(Mandatory=$True)] 
    [string]$bar, 
    [Parameter(Mandatory=$False)] 
    [object[]]$args 
) 
    Write-Output "bar=$bar"; 
    # Test for $args here and process each item in it 

} 
+0

Re“你可以使用带有命名参数的高级函数,它将严格验证参数名称” - 这是否意味着只接受确切的名称?如果是这样,怎么样?在你的例子中运行'Foo -b abc'会打印'bar = abc',所以我没有看到那些参数名已经被严格验证。 (PS 2.0) – bacar

+1

这真的很奇怪,我确信我的第一次运行已经拒绝了'-b',但是我从此关闭了窗口,现在无法再现它。 – alroc

+0

验证非任意参数/参数要容易得多,因为您在设计函数时知道您的输入应该是什么样子。通过PowerShell高级函数提供的内置验证,您可以设计验证要比在函数体中编写额外的逻辑容易得多。这是从原来的问题变得非常关键。 – alroc

2

PowerShell无法禁用对参数的明确前缀匹配的支持。

虽然有各种各样的权衡,但有几个选项。

选项1 - 自己解析参数:

function foo { 
    param() 

    # $args has all of the parameters and arguments 
} 

这是比较困难的给你写的,但解决您希望解决,因为你会完全自己的参数/参数结合的问题。

另一个缺点是参数没有制表符完成,至少在TabExpansion或TabExpansion2中没有一些额外的相应帮助(例如使用TabExpansion ++或PowerTab等模块)。

请注意,在此示例中,即使您的参数为“来自其余参数的值”,您也不希望cmdlet绑定,因为cmdlet绑定会添加常用参数,并且如果使用明确的前缀,那么这些参数将被绑定。

选项2 - 要求主叫做不同的事情

有几个用的cmdlet类似的问题,例如Invoke-Command或Get-Command。两者都接受一组参数。用户必须报价参数:

icm { param($a,$b) $b } -ArgumentList '-b','hello' 

这些cmdlet使用-ArgumentList因为他们真的必须接受可能与小命令的参数冲突任意参数。

如果您的问题受到更多限制,可能还有其他选择,但它需要一些非常常用的语法,并且仍然存在某些参数问题。例如:

function foo 
{ 
    param([Parameter(ValueFromRemainingArguments=$true)]$ArgumentList) 
    $ArgumentList 
} 

foo -- -A 1 -Ar 2 -Arg 3 

特殊标记' - '告诉PowerShell后面的所有内容都是参数。这样,看起来像参数的参数被视为参数。

如果调用者忘记' - ',这种方法可能会引起混淆。

相关问题