gpt4 book ai didi

powershell - 使用扩展字符串作为 Powershell 函数参数

转载 作者:行者123 更新时间:2023-12-04 23:36:54 25 4
gpt4 key购买 nike

我正在尝试编写一个函数,该函数将打印用户提供的问候语,地址是用户提供的名称。我想在这个代码块中使用扩展字符串:

$Name = "World"  
$Greeting = "Hello, $Name!"
$Greeting

成功打印 Hello, World! .但是,当我尝试将这些字符串作为参数传递给这样的函数时,
function HelloWorld
{
Param ($Greeting, $Name)
$Greeting
}
HelloWorld("Hello, $Name!", "World")

我得到输出
Hello, !  
World

经调查,Powershell 似乎忽略了 $Name"Hello, $Name!"完全,作为运行
HelloWorld("Hello, !", "World")

产生与上述相同的输出。此外,它似乎不考虑 "World"作为 $Name 的值, 因为运行
function HelloWorld
{
Param ($Greeting, $Name)
$Name
}
HelloWorld("Hello, $Name!", "World")

不产生任何输出。

当作为函数参数传入时,有没有办法让扩展字符串工作?

最佳答案

为了延迟字符串插值并按需执行,使用当前值 , 你必须 使用 $ExecutionContext.InvokeCommand.ExpandString() [1] 在用作模板的单引号字符串上 :

function HelloWorld
{
Param ($Greeting, $Name)
$ExecutionContext.InvokeCommand.ExpandString($Greeting)
}

HelloWorld 'Hello, $Name!' 'World' # -> 'Hello, World!'
注意 'Hello, $Name!'是单引号以防止即时扩展(插值)。
还要注意 HelloWorld调用时其参数用空格分隔,而不是 , ,并且没有 (...) .
在 PowerShell 中,函数的调用类似于命令行可执行文件 - foo arg1 arg2 - 不像 C# 方法 - foo(arg1, arg2) - 见 Get-Help about_Parsing .
如果你不小心使用了 ,为了分离您的参数,您将构造一个函数将其视为单个参数的数组。
为了帮助您避免意外使用方法语法,您可以使用 Set-StrictMode -Version 2 或更高,但请注意,这需要额外的严格检查。
请注意,由于默认情况下 PowerShell 函数还可以看到在父作用域(所有祖先作用域)中定义的变量,您可以简单地定义模板在调用作用域中引用的任何变量,而不是声明单个参数,例如 $Name。 :
function HelloWorld
{
Param ($Greeting) # Pass the template only.
$ExecutionContext.InvokeCommand.ExpandString($Greeting)
}

$Name = 'World' # Define the variable(s) used in the template.
HelloWorld 'Hello, $Name!' # -> 'Hello, World!'
警告 : PowerShell 字符串插值支持完整的命令 - 例如, "Today is $(Get-Date)" - 所以 除非您完全控制或信任模板字符串 , 这种技术可以是 安全风险。

Ansgar Wiechers建议 基于 .NET string formatting 的安全替代方案通过 PowerShell 的 -f接线员 索引占位符 ( {0} , {1} , ...):
请注意,您不能再对参数应用转换作为模板字符串的一部分,也不能在其中嵌入命令。
function HelloWorld
{
Param ($Greeting, $Name)
$Greeting -f $Name
}

HelloWorld 'Hello, {0}!' 'World' # -> 'Hello, World!'
陷阱:
  • PowerShell 的字符串扩展使用不变的文化,而 -f运算符执行文化敏感格式(片段需要 PSv3+):
      $prev = [cultureinfo]::CurrentCulture
    # Temporarily switch to culture with "," as the decimal mark
    [cultureinfo]::CurrentCulture = 'fr-FR'

    # string expansion: culture-invariant: decimal mark is always "."
    $v=1.2; "$v"; # -> '1.2'

    # -f operator: culture-sensitive: decimal mark is now ","
    '{0}' -f $v # -> '1,2'

    [cultureinfo]::CurrentCulture = $prev
  • PowerShell 的字符串扩展支持扩展集合(数组) - 它将它们扩展为以空格分隔的列表 - 而 -f运算符仅支持标量(单值):
      $arr = 'one', 'two'

    # string expansion: array is converted to space-separated list
    "$var" # -> 'one two'

    # -f operator: array elements are syntactically treated as separate values
    # so only the *first* element replaces {0}
    '{0}' -f $var # -> 'one'
    # If you use a *nested* array to force treatment as a single array-argument,
    # you get a meaningless representation (.ToString() called on the array)
    '{0}' -f (, $var) # -> 'System.Object[]'

  • [1] 呈现 $ExecutionContext.InvokeCommand.ExpandString() 的功能更容易发现的方法,即通过 Expand-String cmdlet,是 GitHub feature-request issue #11693 的主题.

    关于powershell - 使用扩展字符串作为 Powershell 函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51555635/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com