提问人:AlexK 提问时间:1/17/2023 最后编辑:AlexK 更新时间:1/18/2023 访问量:136
如何解决使用 -File 选项调用 PowerShell 脚本的参数中的引号问题?
How to solve problem with quotes in arguments on calling a PowerShell script with -File option?
问:
我想从带有参数的 Windows 10 专业版命令行调用一个小型 PowerShell (v5.1) 脚本。
param($ReqURL, $JSONString)
Write-Host $ReqURL # for debug
Write-Host $JSONString # for debug
Invoke-RestMethod -Uri $ReqURL -Method Patch -ContentType "application/json" -Body $JSONString
在 PowerShell 控制台中调用脚本工作正常:
.\http-patch.ps1 -ReqURL myRESTApi -JSONString '{"lastname": "Bunny"}'
当我转义双引号时,从 Windows 命令提示符 () 调用脚本有效,如下所示:cmd.exe
PowerShell .\http-patch.ps1 -ReqURL myRESTApi -JSONString '{\"lastname\": \"Bunny\"}'
但是当我使用该选项时,它失败了,因为脚本内部等于:-File
$JSONString
'{"lastname":
PowerShell -File "C:\work\LV Demo\http-patch.ps1" -ReqURL myRESTApi -JSONString '{\"lastname\": \"Bunny\"}'
我认为这里有一些引号问题,但我找不到正确的方法。
答:
使用 powershell.exe
(Windows PowerShell CLI)的 -File
参数时,从外部 PowerShell 调用时,只有双引号 (“
) 被识别为具有语法功能,例如:cmd.exe
因此,从 to 切换到(嵌入的字符需要以任何一种方式转义为 (sic):'
"
"
\"
:: From cmd.exe
PowerShell -File "C:\work\LV Demo\http-patch.ps1" -JSONString "{\"lastname\": \"Bunny\"}" -ReqURL myRESTApi
相比之下,当您使用 时,在未转义的字符之后识别字符串。 - 在初始命令行解析期间唯一具有语法功能的标记已被剥离,因为生成的标记随后被解释为 PowerShell 代码。-Command
'...'
"
有关何时使用与何时使用的指导。 以及结果解析的差异,请参阅此答案。-Command
-File
在 PowerShell 内部,很少需要调用另一个 PowerShell 实例,因为可以在进程内直接调用文件。.ps1
如果确实需要从 PowerShell 内部调用 CLI(例如,需要从 PowerShell 内部调用 CLI,即 PowerShell (Core) 的 pwsh.exe
,反之亦然),最佳选择是使用脚本块 ({ ... }
)(仅在从 PowerShell 内部调用时有效),因为:powershell.exe
- 允许你只关注 PowerShell 自己的报价和转义要求。
- 支持接收类型化输出(字符串以外的对象)、基于 XML 的后台序列化,尽管类型保真度有限 - 请参阅此答案。
# From PowerShell
# Note how the " chars. now need NO escaping.
# (If you were to use a "..." string, you'd escape them as `" or "")
PowerShell {
& C:\work\LV Demo\http-patch.ps1" -JSONString '{"lastname": "Bunny"}' -ReqURL myRESTApi
}
虽然可以通过单个参数进行调用,类似于必须从 PowerShell 外部调用的方式,但您不仅会失去类型化输出的好处,而且还会在 PowerShell 7.2.x 之前运行一个长期存在的 bug,该 bug 需要手动转义嵌入的 “
字符。 as \
调用外部程序时 - 请参阅此答案- 正如你自己的一次尝试所证明的那样(在这里,使用是完全可以的,因为 PowerShell 可以识别它):'...'
# !! Note the unexpected need to \-escape the embedded " chars.
PowerShell -File .\http-patch.ps1 -JSONString '{\"lastname\": \"Bunny\"}' -ReqURL myRESTApi
# Variant with double quotes.
# !! Note the *double* escaping: first with ` - for the sake of PowerShell itself -
# !! then with \ due to the bug.
PowerShell -File .\http-patch.ps1 -JSONString "{\`"lastname\`": \`"Bunny\`"}" -ReqURL myRESTApi
评论
JSONString = {\
评论