Powershell:将json字符串传递给curl

Koe*_*enJ 4 powershell curl

我正在尝试使用curl将一个来自powershell脚本的JSON字符串传递给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
Run Code Online (Sandbox Code Playgroud)


实际上,从命令行调用时,这确实运行良好.
但是,当我尝试在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



知道怎么做到这一点?

谢谢你的时间,科恩

mkl*_*nt0 14

更新

  • PowerShell 7.3.0基本上解决了该问题,但Windows有选择性例外- 请参阅此答案以了解详细信息。

  • 对于跨版本、跨版本的代码,Native下面讨论的模块可能仍然令人感兴趣。

长话短说:博士

不幸的是,在Windows PowerShellPowerShell(核心) 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
Run Code Online (Sandbox Code Playgroud)

请继续阅读以了解为什么这是必要的。


  • PowerShell 的转义字符是`(所谓的反引号),因此为了在(双引号、插值)字符串中嵌入 "字符,请使用(或) 而不是; 相比之下,在(单引号、逐字)字符串内部不需要转义"..."`"""\"'...'"

    • 在您的尝试中,PowerShell 没有将\"视为转义 ",因此看到了多个 "..."字符串,最终,当 PowerShell 需要在幕后应用其按需重新引用时,传递了两个单独的字符串参数,这些参数单独不需要双引号,由于不包含空格,即:逐字data={\password\:\keypass\}

    • 使用PowerShell 的引用规则,您应该使用

      • 任何一个:

        • "data={`"password`":`"keypass`"}"
      • 或者,更简单地,假设不需要字符串插值,通过逐字引号字符串,其中"chars. 不需要转义:

        • 'data={"password":"keypass"}'
      • 然而不幸的是,直到 PowerShell 7.2.x,这还不够;请继续阅读以了解详细信息。

  • 到 PowerShell 7.2.x 为止,需要对嵌入字符进行意外的额外转义,在调用(大多数)外部程序时使用-escaping"\

    • Windows PowerShell中,存在这种方法不起作用的边缘情况--%,在这种情况下需要使用(见下文)。值得注意的是,转义'"foo bar"'as'\"foo bar\"'不起作用,因为封闭的\"位于字符串的开头和结尾 - 有关详细信息,请参阅此答案

    • 另外,Windows 上的一些外部程序""仅理解 -escaping(例如msiexec);对于它们,使用-replace '"', '""'以便以编程方式执行额外的转义,假设该值至少包含一个空格。对不支持嵌入"字符的程序执行相同的操作。完全(WSH),这样嵌入"至少不会打破参数边界(但它们将被剥离)。

    • 对于需要\"-escaping 的程序,请使用以下-replace操作以编程方式稳健地执行额外转义

      • '...' -replace '(\\*)"', '$1$1\"'
      • 如果输入字符串不包含预先存在的逐字\"序列,则可以简化为'...' -replace '"', '\"'
# 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
Run Code Online (Sandbox Code Playgroud)
  • 这不应该是必需的,但这是由于 v1 以来的一个错误造成的,由于担心破坏向后兼容性,该错误尚未修复 - 请参阅此答案

  • PowerShell v7.3基本上解决了该问题,但在 Windows 上有选择性例外

  • 向后和向前兼容的辅助函数是来自模块( ) 的ie函数,它消除了额外转义的需要,包含 Windows 上高配置 CLI 的重要调整,并且即使在修复后仍将继续按预期工作。地方:)NativeInstall-Module Native
    ie curl.exe ... -d "data={`"password`": `"$passwd`"}" ...

  • 使用停止解析符号--%(如Keith Hill 的答案所示)是一种次优的解决方法,也不需要额外的\- 转义,但是

    • --%具有固有的局限性 - 请参阅GitHub 文档问题 #6149 - 并且在类 Unix 平台上几乎没有用 - 请参阅GitHub 文档问题 #4963
    • 在后面的参数中嵌入 PowerShell变量值的唯一 - 尴尬且产生副作用 - 的方法--%是 (a) 将它们定义为环境变量(例如$env:passwd = 'foo')和 (b) 引用这些变量cmd.exe-style,即使在 Unix 上也是如此(例如, %passwd%)。
  • 一种解决方法- 特别是当您需要在调用中包含 PowerShell 变量或表达式的值时- 是使用包含整个命令行的单个参数来调用 viacmd /c;为了引用方便,以下示例使用此处字符串(有关 PowerShell 字符串文字的概述,请参阅此答案的底部部分):

# 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
Run Code Online (Sandbox Code Playgroud)


Kei*_*ill 7

尝试使用--%运算符将PowerShell置于简单(哑)参数解析模式中:

curl.exe --% -ku user@email:mypass -X PUT -d "data={\"password\":"\keypass\"}" https://build.phonegap.com/api/v1/key
Run Code Online (Sandbox Code Playgroud)

这通常用于调用具有与PowerShell的参数语法相冲突的参数语法的exes.这确实需要PowerShell V3或更高版本.