【问题标题】:Resolve PowerShell Function Parameter Values Among Parameters解析参数中的 PowerShell 函数参数值
【发布时间】:2011-11-24 20:31:55
【问题描述】:

我试图弄清楚在将包含另一个参数值的参数传递给函数时,如何强制 PowerShell 运行时以表达式模式解析字符串。例如,我想使用第一个参数的值将两个参数传递给带有第二个参数的函数。我知道我需要让解析器在表达式模式下评估第二个参数值,但输出似乎无法解析第一个参数的值。

PowerShell 命令 #1 此示例按预期工作,并证明当使用 2 + 2 左右的子表达式时,该命令在表达式模式下进行计算

& { param($test1,$test2); $test1; $test2 } "foo" "Test 1 value: $(2 + 2)"

输出

foo
Test 1 value: 4

PowerShell 命令 #2 现在,当我尝试相同的方法让参数二 ($test2) 引用参数一 ($test1) 的值时,似乎没有计算表达式,或者至少 $test1 的值是空白或 null。

& { param($test1,$test2); $test1; $test2 } "foo" "Test 1 value: $($test1)"

输出

foo
Test 1 value:

请注意,当我认为应该是“foo”时,Test 1 的值是空白的,这是 $test1 参数中传递的值。关于 PowerShell 函数中的参数范围,我缺少什么?为什么 $test1 值不能在作为 $test2 的值传递的表达式中引用?有没有更优雅的方法来做到这一点?

【问题讨论】:

    标签: function powershell parameters parameter-passing


    【解决方案1】:

    这是因为“表达式”在脚本块之外进行评估,甚至在将参数传递给脚本块之前。

    比如:

    $test1 = 4
    & { param($test1,$test2); $test1; $test2 } "foo" "Test 1 value: $($test1)"
    

    将给出输出:

    foo
    Test 1 value: 4
    

    解决方法:

    & { param($test1,$test2); $test1; & $test2 } "foo" {"Test 1 value: $test1"}
    

    但我想在实际情况下,您不想更改正在使用的脚本块(或函数等)。

    我也会质疑这种情况的必要性,因为您真正想做的是:

    $test1 = "foo"
    $test2 = "Test 1 value: $test1"
    & { param($test1,$test2); $test1; $test2 } $test1 $test2
    

    【讨论】:

    • 感谢您在第二个参数值周围使用脚本块的解决方法。这确实解决了问题并强制表达式模式解析。
    【解决方案2】:

    让我想起了架构\lisp!您可以在该语言中将函数作为参数传递 - 我不知道您是否可以在 PS 中将脚本块作为参数传递。

    不管怎样,你引用变量的名称有什么关系吗?

    如果不是并且您只想引用第一个变量(或您选择的变量),您可以执行以下操作:

     & { $args[0]; $args[1]; "Value of arg #$($args[1]): $($args[$($args[1])])"} "foo" "0"
    

    与其他多个变量一起使用:

    & { $args[0]; $args[1]; "Value of arg #$($args[1]): $($args[$($args[1])])"} "foo" "3" 23 24 25 26
    

    【讨论】:

    • 感谢 args 集合的想法。名称很重要,因为脚本中的参数名称存在内部变量引用。我基本上是通过在其他参数中使用一个参数的值来允许参数相互作用。
    【解决方案3】:

    感谢您的回复,这有助于澄清一些事情。最终,我想将参数从数据库传递给脚本。参数值包括对其他 PowerShell 参数的引用,并且在脚本运行之前无法解析它们。我在 IIS 中运行 PowerShell 运行空间,但我不知道如何强制解析器使用标准的 "" 字符来评估表达式。

    唉,我发现 PowerShell 中的 $ExecutionContext.InvokeCommand.ExpandString() 函数正是我需要的。这个函数实际上是由 http://powershell.com/cs/blogs/ebook/archive/2009/03/30/chapter-12-command-discovery-and-scriptblocks.aspx#executioncontext 中记录的 "" 字符在幕后执行的。

    做我想做的事需要一些额外的工作,但我能够使用以下模式来解析脚本中的值。这会强制解析器在表达式模式下重新评估 $test2 并执行变量替换,从而生成包含正确变量值的字符串。

    $test2 = $ExecutionContext.InvokeCommand.ExpandString($test2)
    

    再次感谢 cmets 和指导!

    【讨论】:

    • 很高兴你发现了,我猜你之后会使用& $test2 执行 $test?顺便说一句,如果这是你应该标记的答案,左边的勾就可以了。 :-)
    • 之后我实际上并没有使用 & $test2 语法执行命令。相反,变量值被解析并替换为原始字符串,以便在脚本中进一步使用。关键是强制解析器使用 PowerShell 中的 ExpandString 函数重新评估变量。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-11
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多