提问人:KoenJ 提问时间:7/15/2014 最后编辑:mklement0KoenJ 更新时间:7/28/2023 访问量:19475
Powershell:将 json 字符串传递给 curl
Powershell: passing json string to curl
问:
我正在尝试使用 curl 将 JSON 字符串从 powershell 脚本中传递到 build.phonegap.com api。
根据 phonegap 的论坛,在 Windows 机器上运行时,JSON 数据必须格式化为:
curl.exe -ku user@email:mypass -X PUT -d "data={\"password\":\"keypass\"}" https://build.phonegap.com/api/v1/key
事实上,当从命令行调用时,它确实运行良好。
但是,当我尝试从 powershell 脚本中调用它时,双引号似乎被剥离了。
到目前为止,我已经尝试过:
- 将 JSON 放在单引号字符串中:
curl.exe -ku user@email:mypass -X PUT -d '"data={\"password\":\"keypass\"}"' https://build.phonegap.com/api/v1/key
- 将 JSON 放在单引号字符串中,不带 DOS 转义反斜杠:
curl.exe -ku user@email:mypass -X PUT -d '"data={"password":"keypass"}"' https://build.phonegap.com/api/v1/key
- 将 JSON 放在单引号字符串中,转义双引号和反斜杠(带有反斜杠的 DOS 样式):
curl.exe -ku user@email:mypass -X PUT -d '\"data={\\\"password\\\":\\\"keypass\\\"}\"' https://build.phonegap.com/api/v1/key
- 将 JSON 放在双引号字符串中,并使用 powershell 反引号字符 () 转义双引号:
`
curl.exe -ku user@email:mypass -X PUT -d "`"data={\`"password\`":\`"build*2014`\`"}`"" https://build.phonegap.com/api/v1/key
知道如何实现这一目标吗?
感谢您抽出时间接受采访, 科恩
答:
设置内容类型:
curl -H "Content-Type: application/json" -d '{"password":"keypass"}' https://build.phonegap.com/api/v1/key
评论
curl
Invoke-WebRequest
curl.exe
Get-Alias
curl
curl.exe
尝试使用运算符将 PowerShell 置于简单(哑)参数分析模式:--%
curl.exe --% -ku user@email:mypass -X PUT -d "data={\"password\":\"keypass\"}" https://build.phonegap.com/api/v1/key
这对于使用与 PowerShell 的参数语法相冲突的参数语法调用 exe 通常很有用。这确实需要 PowerShell V3 或更高版本。
评论
--%
更新:
PowerShell 7.3.0 主要解决了这个问题,但在 Windows 上有选择性的例外 - 有关详细信息,请参阅此答案。
对于跨版本、跨版本代码,下面讨论的模块可能仍然值得关注。
Native
tl;博士:
不幸的是,在 Windows PowerShell 和 PowerShell (Core) v7.2.x 及之前的版本中,必须手动 \
-转义传递给外部程序的参数中嵌入的“字符。
# From inside PowerShell:
# Note the outer '...' quoting and the unexpected need to escape
# the embedded " chars. as \" (unexpected, because PowerShell itself doesn't
# require " inside '...' to be escaped; also, PowerShell's escape char. is `).
# If outer "..." quoting must be used, use \`" (sic) to escape the embeded "
curl.exe -ku user@email:mypass -X PUT -d 'data={\"password\":\"keypass\"}' https://build.phonegap.com/api/v1/key
请继续阅读,了解为什么这是必要的。
PowerShell 的转义字符
是 '(所谓的反引号),因此为了在(双引号、插值)字符串中嵌入字符,请使用
'“
(或 )而不是 ;相比之下,在(单引号,逐字)字符串中,不需要转义。"
"..."
""
\"
'...'
"
在您的尝试中,PowerShell 没有看到转义,因此看到了多个字符串,最终 - 当 PowerShell 在幕后应用其按需重新引用时,传递了两个单独的字符串参数,这些参数由于不包含空格,因此不需要双引号,即:逐字逐句和
\"
"
"..."
data={\
password\:\keypass\}
使用 PowerShell 的引用规则,你应该使用:
也:
"data={`"password`":`"keypass`"}"
或者,更简单地说,假设不需要字符串插值,通过一个逐字的单引号字符串,其中的字符。 不需要转义:
"
'data={"password":"keypass"}'
然而,不幸的是,直到 PowerShell 7.2.x 这还不够;请继续阅读了解详情。
在 PowerShell 7.2.x 之前,在
调用(大多数)外部程序时,需要对嵌入
的“
字符进行意外的额外转义层:在 Windows PowerShell 中,在一些极端情况下,此方法不起作用,在这种情况下,需要使用 (见下文)。值得注意的是,由于括号位于字符串的开头和结尾,因此转义是行不通的 - 有关详细信息,请参阅此答案。
--%
'"foo bar"'
'\"foo bar\"'
\"
此外,Windows 上的某些外部程序仅理解 -escaping(例如);对于它们,use in 以便以编程方式执行额外的转义,假设该值至少包含一个空格。对根本不支持嵌入式字符的程序 (WSH) 执行相同的操作,以便嵌入的至少不会破坏参数边界(但它们将被剥离)。
""
msiexec
-replace '"', '""'
"
"
对于期望
\“
-转义的程序,请使用以下操作以编程方式可靠地执行额外的转义:-replace
'...' -replace '(\\*)"', '$1$1\"'
- 如果输入字符串不包含预先存在的逐字序列,则可以简化为
\"
'...' -replace '"', '\"'
# Note: Escaping the embedded " chars. as `" is enough for PowerShell itself,
# but, unfortunately, not when calling *external programs*.
# The `-replace` operation performs the necessary additional \-escaping.
$passwd = 'foo'
curl.exe -ku user@email:mypass -X PUT -d (
"data={`"password`": `"$passwd`"}" -replace '(\\*)"', '$1$1\"'
) https://build.phonegap.com/api/v1/key
这不应该是必需的,但这是由于自 v1 以来的一个错误,由于担心破坏向后兼容性而尚未修复 - 请参阅此答案。
PowerShell v7.3 主要解决了这个问题,但在 Windows 上有选择性的例外。
选择性异常 - 请参阅
$PSNativeCommandArgumentPassing
首选项变量的描述 - 是不幸的,因为它们保留了异常列表中程序的旧损坏行为,特别是 WSH(Windows 脚本主机)可执行文件及其关联的脚本文件 (, , , , ),并有可能将来零碎地添加到异常列表中 - 请参阅 GitHub 问题 #18660 中的此摘要cmd.exe
.cmd
.bat
.js
.vbs
.wsf
可悲的是,通过对 Windows 上备受瞩目的 CLI 进行幕后调整,避免了这些异常需求的机会被错过了;请参阅 GitHub 问题 #15143 中的此摘要。
向后和向前兼容的帮助程序函数是
Native
模块 () 中的ie
函数,它消除了额外转义的需要,包含 Windows 上高配置 CLI 的重要调整,并且即使修复到位,也将继续按预期工作:Install-Module Native
ie curl.exe ... -d "data={`"password`": `"$passwd`"}" ...
)使用 --
%
,停止解析符号,如 Keith Hill 的答案所示,是一种次优的解决方法,也不需要额外的 -转义,但是:\
--%
具有固有的局限性 - 请参阅 GitHub 文档问题 #6149 - 并且在类 Unix 平台上几乎毫无用处 - 请参阅 GitHub 文档问题 #4963。- 在以下参数中嵌入 PowerShell 变量值的唯一笨拙且产生副作用的方法是 (a) 将它们定义为环境变量(例如 ),并且 (b) 引用这些变量
cmd.exe
样式,即使在 Unix 上也是如此(例如,)。--%
$env:passwd = 'foo'
%passwd%
另一种解决方法(尤其是需要在调用中包含 PowerShell 变量或表达式的值时)是通过
cmd /c
使用包含整个命令行的单个参数进行调用;为方便起见,以下示例使用 here-string(有关 PowerShell 字符串文本的概述,请参阅此答案的底部部分):
# Use @"<newline>...<newline>"@ if you need to embed PowerShell variables / expressions.
cmd /c @'
curl.exe -ku user@email:mypass -X PUT -d "data={\"password\":"\keypass\"}" https://build.phonegap.com/api/v1/key
'@
评论
curl.exe -d '{"north": "east west"}' https://reqbin.com/echo/post/json
cmd.exe
cmd.exe
cmd.exe
以下是我如何在 PowerShell 7.2 中发送 json 请求
评论
终于找到了解决方案。Inot 使用一个使用 3 个 (),仅此而已。所以它会是:"
"""
data={"""password""":"""keypass"""}
评论
pwsh -nop -c ' bash -c ''printf """""""\\033[38;2;255;0;0mHi\\033[0m"""""""'' '
powershell.exe
pwsh
-Command
-c
"
-Command
\"
cmd.exe
"^""
powershell.exe
""
pwsh.exe
评论
the double quotes seem to be stripped.
你怎么断言?PSNativeCommandArgumentPassing
可能需要选择加入 - 假设它成为官方功能。"
\