gpt4 book ai didi

powershell - 在PowerShell中使用变量将多个参数传递给外部程序

转载 作者:行者123 更新时间:2023-12-02 23:18:15 24 4
gpt4 key购买 nike

我下载了npm软件包以合并junit报告-https://www.npmjs.com/package/junit-merge

问题是我有多个文件要合并,并且我试图使用字符串变量来保存要合并的文件名。

当我编写脚本myslef时,如下所示:

junit-merge a.xml b.xml c.xml 

这有效,正在创建合并文件,但是当我这样做时
$command = "a.xml b.xml c.xml"
junit-merge $command

这是行不通的。错误是

Error: File not found



有没有人遇到过类似的问题?

最佳答案

$command = "a.xml b.xml c.xml"; junit-merge $command



会在命令行中生成 junit-merge "a.xml b.xml c.xml" [1],即将字符串 a.xml b.xml c.xml作为单个参数传递给 junit-merge,这不是故意的。

在这方面,PowerShell的行为不像 bash这样的POSIX shell 程序那样:在 bash中,变量 $command的值(由于未引用而引起的)将受到分词(所谓的 shell expansions)的影响导致3个不同的参数(尽管最好是基于数组的调用)。
PowerShell不支持类似于bash的shell扩展[2];它具有不同的,通常更灵活的构造,例如下面讨论的splatting技术。

相反, 将您的参数定义为数组的各个元素,如 justnotme建议:
# Define the *array* of *individual* arguments.
$command = "a.xml", "b.xml", "c.xml"

# Pass the array to junit-merge, which causes PowerShell
# to pass its elements as *individual arguments*; it is the equivalent of:
# junit-merge a.xml b.xml c.xml
junit-merge $command

这是 的一种应用程序,这是一种称为splatting 的PowerShell技术,您可以在其中指定要通过变量传递给命令的参数:
  • 两种(通常情况下,仅用于外部程序):
  • 作为参数的数组,分别作为位置参数传递,如上所示。
  • 或(通常在调用PowerShell命令时):
  • 作为哈希表来传递命名参数值,在该哈希表中,您必须$ 替换变量引用中的@标记;例如,在您的情况下@command;例如,以下等效于调用Get-ChildItem C:\ -Directory:
  • $paramVals = @{ LiteralPath = 'C:\'; Directory = $true }; Get-ChildItem @paramVals


  • 请注意基于数组的溅出:

    由于 this GitHub issue中详细描述了一个错误,因此 PowerShell不会将空参数传递给外部程序(从Windows PowerShell 5.1 / PowerShell [Core] 7.0开始仍然适用,并且可能永远不变以保持向后兼容性)。

    例如, foo.exe ""意外导致仅 foo.exe被调用。

    此问题同样会影响基于数组的展开,因此 $cmdArgs = "", "other"; foo.exe $cmdArgs生成 foo.exe other而不是预期的 foo.exe "" other

    与基于数组的一起可选地使用 @:

    您也可以将 @标记符与数组一起使用,因此也可以使用:
    junit-merge @command

    但是,有一个细微的区别。

    在实践中,这几乎无关紧要,
    较为安全的选择是使用$ ,因为它可以防止(无论是假设性的)意外误解您打算成为文字的 --%数组元素。

    @语法将数组元素 --%识别为特殊的 stop-parsing symbol, --%

    该符号告诉PowerShell不要像通常那样解析其余的参数,而是按原样传递它们,除了扩展 cmd.exe样式的变量引用(例如 %USERNAME%)外。

    通常,这仅在不使用喷溅时才有用,通常是在能够按原样使用PowerShell中为 cmd.exe编写的命令行的情况下,而无需考虑PowerShell的语法差异。

    但是,在进行喷溅时,由 --%引起的行为是不明显的,最好避免:
  • 与直接传递参数时一样,--%从结果命令行中删除。
  • 参数边界丢失,因此通常在命令行上作为foo bar放置的单个数组元素"foo bar"被作为foo bar放置,即有效地作为2个参数。


  • [1]您的调用意味着打算将变量 $command的值作为单个参数传递,因此,当PowerShell在幕后构建命令行时,它将双引号 a.xml b.xml c.xml中包含的逐字 $command字符串以确保这一点。请注意,这些双引号与最初为 $command分配值的方式无关。
    不幸的是,这种自动报价被嵌入的 " chars破坏了。 -例如,参见 this answer

    [2]为了表示类似POSIX的 shell ,PowerShell确实执行了一种 shell 扩展,但是(a)仅在类似Unix的平台(macOS,Linux)上,并且(b)仅在调用外部程序时:无引号的通配符模式,例如因为当您调用外部程序(例如 *.txt)时, /bin/echo *.txt确实扩展为它们的匹配文件名,PowerShell调用了本地globlob的功能。

    关于powershell - 在PowerShell中使用变量将多个参数传递给外部程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59069918/

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