powershell - 函数参数位置突然表现得很奇怪

标签 powershell parameter-passing pipeline positional-parameter

代码:

这个例子说明了我的意思:

Function test{
    param(
    [parameter(Position = 0, ValueFromPipeline)]
    [string]$Param0,
    [parameter(Position = 1)]
    [ArgumentCompletions("Param1_Opt1", "Param1_Opt2")]
    [Array]$Param1 = ('Param1_Opt3', 'Param1_Opt4'),
    [switch]$NoHeader
    )
    "This is $Param0"
    "Header :$Param1"
}

我的问题:

很长一段时间以来,我今天在编写函数时一直依赖所有函数中的参数位置,突然它停止了我使用它们的方式。上面的 test 函数演示了这个问题。

如果参数具有参数 Position = 0 属性,并且还具有 ValueFromPipeline 属性。当它用于管道时。具有 Position 属性的下一个参数占据其位置。这也意味着会建议下一个参数 ArgumenCompletions,例如 "Param1_Opt1"/"Param1_Opt2"

但我根本没有得到这种行为。

Test "This is For Parameter Zero" "This is For Parameter One"

---- Ouput -----
This is For Parameter Zero
This is For Parameter One

以上内容按预期工作,第一个字符串正确分配给 Param0,第二个字符串正确分配给 Param1,更多 Param1 参数建议有效,但以下操作失败并出现错误,并且管道字符串被分配给 Param1。另外 Param1 参数补全不起作用:

"This is For Parameter Zero" | Test "This is For Parameter One"
---- Error ----
test: The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.
--- OutPut ----
This is For Parameter One
Header :Param1_Opt0 Param1_Opt0

期望的输出:

Test "This is For Parameter Zero" "This is For Parameter One"

---- Ouput -----
This is For Parameter Zero
This is For Parameter One

以上是我在正常使用中所期望的,以下是使用管道时以及 Param1 参数建议起作用的情况:

"This is For Parameter Zero" | Test "This is For Parameter One"

---- Ouput -----
This is For Parameter Zero
This is For Parameter One

最佳答案

Santiago在评论中提供了关键的指针,但让我把它拼写出来:

在基于管道的调用中,您需要使用命名参数来绑定(bind)到-Param1:

# Note the required use of -Param1
"This is For Parameter Zero" | Test -Param1 "This is For Parameter One"

之所以需要这样做,是因为参数绑定(bind)的顺序:

  • 在命令开始执行之前,首先绑定(bind)参数提供的输入。

  • 只有稍后,当管道输入处理开始时,才会在每个管道输入对象上执行参数绑定(bind)。

  • 至于为什么 PowerShell 必须以这种方式绑定(bind)参数:

    • 传递给命令的参数按照设计预先进行评估,并且评估结果一次绑定(bind)到目标参数 em>,在命令开始执行之前。

    • 管道输入通常事先不知道,因为它仅在输入提供命令执行时产生。

    • 此外,提供输入的命令发出的对象的数据类型通常未知,并且命令可以自由地发出对象>不同的类型,因此每个发出的对象可以不同绑定(bind)到接收命令的参数。

    • 简而言之:没有办法静态地预先确定管道输入将如何绑定(bind)到参数,因此它必须推迟到运行时,并且必须为每个参数单独执行输入对象。

因此:

  • “这是参数零” |首先测试“This is For Parameter One” 绑定(bind)参数 “This is For Parameter One”单独进行,不考虑潜在的管道输入,并且,鉴于它是第一个位置参数,它绑定(bind)到参数-Param0

  • 然后,当管道输入处理开始时,PowerShell 尝试将管道对象“这是参数零”绑定(bind)到尚未-bound-by-arguments 参数,并且由于函数唯一的管道绑定(bind)参数 -Param0 已绑定(bind),因此参数绑定(bind)失败,导致您看到的错误。

    • 通过参数名称将参数绑定(bind)到 -Param1 可以避免此问题。

关于powershell - 函数参数位置突然表现得很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76854339/

相关文章:

powershell - 尝试在 powershell 中显示 gif

Javascript 如何通过引用传递 int

c++ - 将类的所有变量传递给函数

Gitlab管道规则: how to not run a job when a branch has an open merge request?防止重复管道

java - Java 中的异步开源工作流软件

powershell - PSake 扩展?

powershell - 作为版本 2 运行远程 Powershell session

powershell - 每个循环中的Powershell启动过程

javascript - 将选定元素从 jQuery UI Selectable 传递到 Rails Controller

python - 在FeatureUnion中绑定(bind)变压器的输出