Powershell 非位置,可选参数

Posted

技术标签:

【中文标题】Powershell 非位置,可选参数【英文标题】:Powershell non-positional, optional params 【发布时间】:2012-09-04 17:59:55 【问题描述】:

我正在尝试创建一个 powershell (2.0) 脚本,该脚本将接受遵循此基本模式的参数:

.\script name [options] PATH

其中 options 是任意数量的可选参数 - 按照“-v”的行来考虑详细信息。 PATH 参数将只是最后传入的任何参数,并且是强制性的。可以在没有选项且只有一个参数的情况下调用脚本,并且该参数将被假定为路径。我在设置仅包含可选参数但也是非位置参数的参数列表时遇到问题。

这个快速脚本演示了我遇到的问题:

#param test script
Param(
    $firstArg,
    $secondArg,
    [switch]$thirdArg,
    [Parameter(ValueFromRemainingArguments = $true)]
    $remainingArgs)

write-host "first arg is $firstArg"
write-host "second arg is $secondArg"
write-host "third arg is $thirdArg"
write-host "remaining: $remainingArgs"

当这样调用时:

.\param-test.ps1 firstValue secondValue

脚本输出:

first arg is firstValue
second arg is secondValue
third arg is False
remaining:

尝试创建的行为会使两个参数都落在可选参数中并最终出现在剩余Args 变量中。

This question/answer 很有帮助地提供了一种实现所需行为的方法,但它似乎只有在至少有一个强制参数时才有效,并且只有当它出现在所有其他参数之前

我可以通过强制 firstArg 并将位置指定为 0 来演示此行为:

#param test script
Param(
    [Parameter(Mandatory=$true, Position = 0)]
    $firstArg,
    $secondArg,
    [switch]$thirdArg,
    [Parameter(ValueFromRemainingArguments = $true)]
    $remainingArgs)

    write-host "first arg is $firstArg"
    write-host "second arg is $secondArg"
    write-host "third arg is $thirdArg"
    write-host "remaining: $remainingArgs"

使用与之前相同的输入运行:

.\param-test.ps1 firstValue secondValue

输出如下:

first arg is firstValue
second arg is
third arg is False
remaining: secondValue

第一个强制参数被赋值,剩下的所有东西都一直掉下去。

问题是这样的:如何设置一个参数列表,使得 所有 参数都是可选的,而 没有一个 是位置的?

【问题讨论】:

【参考方案1】:

这个怎么样?

function test

   param(
      [string] $One,

      [string] $Two,

      [Parameter(Mandatory = $true, Position = 0)]
      [string] $Three
   )

   "One = [$one]  Two = [$two]  Three = [$three]"

OneTwo 是可选的,只能通过名称指定。 Three 是强制性的,可以不提供名称。

这些工作:

test 'foo'
    One = []  Two = []  Three = [foo]
test -One 'foo' 'bar'
    One = [foo]  Two = []  Three = [bar]
test 'foo' -Two 'bar'
    One = []  Two = [bar]  Three = [foo]

这将失败:

test 'foo' 'bar'
test : A positional parameter cannot be found that accepts argument 'bar'.
At line:1 char:1
+ test 'foo' 'bar'
+ ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [test], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,test

这并不强制你的强制参数放在最后,或者它没有被命名。但它允许你想要的基本使用模式。

它也不允许$Three 中有多个值。这可能是你想要的。但是,如果您想将多个未命名参数视为 $Three 的一部分,则添加 ValueFromRemainingArguments 属性。

function test

   param(
      [string] $One,

      [string] $Two,

      [Parameter(Mandatory = $true, Position = 0, ValueFromRemainingArguments = $true)]
      [string] $Three
   )

   "One = [$one]  Two = [$two]  Three = [$three]"

现在这样的工作:

test -one 'foo' 'bar' 'baz'
  One = [foo]  Two = []  Three = [bar baz]

甚至

test 'foo' -one 'bar' 'baz'
    One = [bar]  Two = []  Three = [foo baz]

【讨论】:

正是我需要的。我没有想到我可以使用 Position=0 的强制 arg 作为 last 参数。 感谢 latkin,我已经为此花费了一个小时。我在这里有另一个问题(我已经回答了你):***.com/questions/18861701/…

以上是关于Powershell 非位置,可选参数的主要内容,如果未能解决你的问题,请参考以下文章

如何在PowerShell中定义多组互斥参数?

如何检查调用者是否设置了PowerShell可选参数

使 URL 接受参数作为可选参数。非捕获

Argparse - 子解析器中位置参数之前的可选参数

如何在 argparse 中使用带有 nargs='*' 参数的可选位置参数?

Dart语法之可选参数