【问题标题】:Why does PowerShell split arguments at spaces when invoked by a batch script and how to fix it?为什么PowerShell在批处理脚本调用时会在空格处拆分参数以及如何修复它?
【发布时间】:2021-05-10 00:47:42
【问题描述】:

非常简单的设置,请在家尝试一下。

test.ps1

$args

test.rb(如有必要,替换为所选语言)

p ARGV

test.bat

@echo off
ruby test.rb "foo bar moo"
powershell .\test.ps1 "foo bar moo"
pause

运行 test.bat。猜猜输出。

如果你和我一样想,那你就错了。

输出

["foo bar moo"]
foo
bar
moo

Ruby 是我的见证,这三个词作为单个参数传递。以比尔·盖茨的名义,PowerShell 在做什么?我怎样才能使它合乎逻辑地工作?

或者我错过了什么?

【问题讨论】:

  • 好的,我至少找到了解决方法:powershell .\test.ps1 """foo bar moo"""。所以它需要转义引号?但为什么呢?

标签: powershell


【解决方案1】:

为了调用带有参数的脚本文件 (.ps1),请使用PowerShell CLI-File参数,而不是(隐含的)-Command 参数:

powershell -File .\test.ps1 "foo bar moo"

请注意,PowerShell (Core)pwsh,PowerShell 版本从 v6 开始)现在默认-File[1]


至于你尝试了什么

powershell .\test.ps1 "foo bar moo"

隐含相同(您也可以使用-c 代替-Command):

powershell -Command .\test.ps1 "foo bar moo"

这会导致 PowerShell 分两个阶段评估参数:

  • 首先,将单个参数周围的句法"剥离,然后将生成的参数与空格连接以形成单个字符串。

  • 其次,生成的字符串 - 在这种情况下为 .\test.ps1 foo bar moo - 然后被解释为作为 PowerShell 源代码,并且如您所见,到那时原始的 " 已被剥离,结果在接收 3 个参数的脚本中。

注意:

  • -Command 的行为也适用于根据 PowerShell 的规则对参数进行额外解释,这与 -File 不同。例如,
    powershell -File .\test.ps1 $HOME 会将$HOME 逐字 传递给脚本,而
    powershell -Command .\test.ps1 $HOME传递 PowerShell 的自动 $HOME 变量的值 .

  • 对于-Command,传递" 字符,这些字符将成为正在评估的结果PowerShell 代码的一部分,确实需要转义

    • 从 Windows PowerShell 的角度来看,最可靠的形式是 \"(原文如此),尽管从批处理文件/cmd.exe 调用时这可能会导致命令行损坏
    • 幸运的是,PowerShell(核心)现在强大地支持"",这避免了批处理文件/cmd.exe 问题。
  • 有关何时使用-File-Command 的更多指导,请参阅this answer


[1] 期望 -File 而不是 -Command 成为 默认 参数是可以理解的,因为大多数 shell 和脚本引擎 CLI 都需要 显式 参数(通常为-c-e)传递命令字符串 而不是脚本文件路径。幸运的是,在 PowerShell (Core) 7+ 中,-File 现在默认设置,这是支持 Unix 上的 shebang 行所必需的更改。
此外,大多数 shell 和脚本引擎 CLI 都希望将命令字符串作为 单个 参数传递,然后将任何其他参数变成参数传递给命令字符串中的代码 ,而 PowerShell 只是将多个参数拼接在一起,然后将结果解释为命令字符串;见GitHub issue #4024

【讨论】:

  • TL;DR:RTFM。感谢您对此进行解释。我不知何故确信只传递文件和参数就是要走的路。可能是因为它在过去巧合地起作用。
  • @Neonit,是的,它可以工作。鉴于大多数 CLI 需要显式参数来传递命令字符串,例如 -c-e,因此期望 -File 是默认值而不是 -Command 是可以理解的。幸运的是,在 PowerShell (Core) 7+ 中,-File 现在 默认值(这是在 Unix 上支持 shebang 行所必需的)。我还将此信息作为答案的脚注包含在内,并添加了指向答案的链接,该答案提供了有关-File cs 的进一步指导。 -Command.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-22
  • 2011-03-25
  • 2013-07-30
  • 1970-01-01
  • 2020-01-05
  • 2022-01-18
  • 1970-01-01
相关资源
最近更新 更多