简而言之
如果你正在从 PowerShell 调用另一个 PowerShell 实例,请使用 脚本块 ({ ... }
) 来获得可预测的行为:
Windows PowerShell:
powershell.exe { .\TestQuotes.ps1 -Config "A B C" }
PowerShell 核心:
pwsh { .\TestQuotes.ps1 -Config "A B C" }
这将使参数引用按预期工作,甚至将返回 对象,因为采用了类似于 PowerShell 远程的序列化。
但请注意,当从 PowerShell 外部,例如从 cmd.exe
或 bash
中调用时,这不是一个选项。
继续阅读以了解在没有脚本块的情况下看到的行为的解释。
PowerShell CLI(调用powershell.exe
(Windows PowerShell)/ pwsh.exe
(PowerShell Core)仅支持一个接受位置参数的参数(即,不带有参数名称的值,如-Command
)。
如果有的话,第一个位置参数之后的任何参数都被视为:
传递给
-Command
的参数(无论是隐式还是显式)会被PowerShell进行
两轮解析,这可能会很棘手:
应用于您的调用,这意味着
同时PowerShell .\TestQuotes.ps1 -Config "A B C"
和
PowerShell .\TestQuotes.ps1 -Config 'A B C'
最终都会解析并执行以下代码:
.\TestQuotes.ps1 -Config A B C
这意味着,由于两轮解析,原始引用被丢失,导致传递了三个不同的参数,这解释了你的症状。
如果你必须让你的命令在
没有脚本块的情况下工作,你有两个选择:
使用 -File
,它只适用于一轮解析:
powershell.exe -File .\TestQuotes.ps1 -Config "A B C"
- 也就是说,除了去掉封闭的
"..."
之外,结果参数被视为字面量 - 然而,这通常是你想要的。
使用(隐含的)-Command
,应用一个额外的引号层次:
powershell.exe -Command .\TestQuotes.ps1 -Config "'A B C'"
命令行解析期间,外部的 "..."
会被剥离,只留下内部的单引号字符串 'A B C'
作为要执行的代码的一部分。
如果您还想在内部使用 "
进行引用(在这里不是必需的),则必须从 PowerShell 的外部使用 "\"A B C\""
和从 PowerShell 的内部使用 "\`"A B C\`""
[1] - 也就是说,PowerShell 要求在传递给其 CLI 的参数中必须将 "
字符转义为 \"
,而在 PowerShell 内部,则必须使用 `"
(或""
)。
[1] \
转义符与 `
一起使用时本来不应该是必需的,但不幸的是,由于长期存在的错误,至少在 PowerShell 7.2.x 中仍然需要使用。这个问题可能会在 7.3 版本中得到修复 - 参见 this answer
powershell.exe /?
来获取一些想法,主要是关于如何将字符串传递给可执行文件的方式不同。 - Lee_Dailey