首页 > 解决方案 > 你能在 PowerShell 中使用位置参数吗?

问题描述

PowerShell 是否支持位置参数的飞溅而不是命名参数?

标签: powershellsyntaxparameter-passing

解决方案


PowerShell 的参数 splatting(请参阅参考资料Get-Help about_Splatting)提供了两种基本选择:

  • 通过哈希表喷溅:适用于命名参数(例如,-Path C:\Windows
  • 通过类似数组的值进行喷溅:适用于位置参数(例如,C:\Windows)-除了将所有[未绑定] 参数传递给另一个命令非高级函数(即,通过喷溅包含所有未绑定参数的自动数组变量,在这种情况下,也支持命名参数,因为只有内置的魔法。@args$args@args

注意:当将参数传递给PowerShell cmdlet/函数(带有声明的参数)时,这种二分法适用,而外部程序执行它们自己的参数解析,这可能会或可能不会解释按命名传递的参数集。[1]

也就是说,您可以任何一种形式与常规的单个参数传递结合起来——使用单个位置参数、单个命名参数、散列表和数组喷的任意组合。

在这两种情况下,源数据结构必须是:

  • 预先存储在变量中。

  • sigil@而不是$.

注意:本RFC中详细介绍的未来增强功能可能会带来直接 splat 表达式的能力,而无需中间变量,尽管从 PowerShell Core 7 开始尚不清楚何时实现。


例子

# Positional binding via *array*. 
# Note that a function's / script block's parameters are by default positional.
PS> $posArgs = 'one', 'two'; & { param($foo, $bar) "`$foo: $foo"; "`$bar: $bar" } @posArgs
$foo: one
$bar: two


# Named binding via *hashtable*
PS> $namedArgs=@{bar='two';foo='one'}; & { param($foo, $bar) "`$foo: $foo"; "`$bar: $bar" } @namedArgs
$foo: one
$bar: two

# *Combining* hashtable splatting with a regular, positional argument
PS> $namedArgs=@{bar='two'}; & { param($foo, $bar) "`$foo: $foo"; "`$bar: $bar" } @namedArgs one
$foo: one
$bar: two     

[1] 与外部程序喷溅:

通常,调用外部程序时不需要splatting,因为:

  • 您可以按原样传递数组(使用通常的$印记)

    • 唯一的例外是,如果您想在参数数组中包含%--停止解析符号(请参阅Get-Help about_Parsing,在参数数组中;您确实需要@在该事件中使用 sigil。

    • 使用单独的数组元素来满足外部程序的语法要求,包括它的命名参数,如果有的话
      (例如,$args = '/c', 'ver'; cmd $args执行cmd /c ver)。

  • 哈希表 splat被翻译成命令行标记的方式可能会或可能不会被外部程序识别:

    • 具体来说,带有键<paramName>和值的哈希表条目<value>被转换为单个参数,其格式为-<paramName>:<value>- 很少有外部命令行实用程序能够识别的格式。

推荐阅读