【问题标题】:Powershell & Curl - Using variables inside single-quoted JSON bodyPowershell & Curl - 在单引号 JSON 正文中使用变量
【发布时间】:2016-03-15 05:55:44
【问题描述】:

我目前正在尝试使用 Powershell 和 Curl 在我们的 Zendesk 票务系统中自动创建新用户。我遇到的问题是 curl json 正文用单引号括起来,我需要在该正文中引用一个变量。这是我所拥有的:

$Firstname = "Test"
$Lastname = "User"
$email= 'user@test.org'   
curl.exe https://mydomain.zendesk.com/api/v2/users.json -H "Content-Type: application/json" -X POST -d '{\"user\": {\"name\": \"$Firstname $Lastname\", \"email\": \"$email\"}}' -v -u myuser:mypass

如果我在 json 中输入常规文本值,这可以正常工作,但是如何让它识别变量 $Firstname、$Lastname 和 $email?

【问题讨论】:

    标签: json powershell curl


    【解决方案1】:

    尝试以下方法:

    $Firstname = "Test"
    $Lastname = "User"
    $email= 'user@test.org'   
    $json=@"
    {\"user\": {\"name\": \"$Firstname $Lastname\", \"email\": \"$email\"}}
    "@
    curl.exe https://mydomain.zendesk.com/api/v2/users.json -d $json -H 'Content-Type: application/json' -X POST -v -u myuser:mypass
    

    使用双引号 here-string @"<newline>...<newline>"@ 可以很容易地指定嵌入的 " 实例(因为需要 PowerShell 的 自己的 语法而无需转义),而仍在扩展变量引用 - 请参阅 docs onlineGet-Help about_Quoting_Rules

    您清楚地意识到 -不幸-额外需要 \-escape " 实例,但只是为了解释为什么需要这样做:

    将参数传递给外部程序时,PowerShell在自己的解析和插值之后,有条件地将结果参数包装在中双引号 连接它们以形成参数列表(单个字符串)以传递给外部实用程序。不幸的是,这可能会导致嵌入 " 实例被丢弃,而可靠地保存它们的唯一方法是\-转义它们 - 请参阅this answer 了解更多信息。

    如果您想使用常规的双引号字符串内联,则必须转义 PowerShell too" 实例(如 `"),从而导致尴尬组合\`"

    "{\`"user\`": {\`"name\`": \`"$Firstname $Lastname\`", \`"email\`": \`"$email\`"}}"
    

    事后考虑

    Ryan 本人在评论中指出,使用 hashtable 构造数据,然后使用 ConvertTo-Json 将其转换为 JSON 和通过标准输入将其提供给curl 是一种避免引用头痛的替代方法:

    # Create data as PS hashtable literal.
    $data = @{ user = @{ name = "$Firstname $Lastname"; email = "$adUsername@mydomain.org" } }
    
    # Convert to JSON with ConvertTo-Json and pipe to `curl` via *stdin* (-d '@-')
    $data | ConvertTo-Json -Compress | curl.exe mydomain.zendesk.com/api/v2/users.json -d '@-' -H "Content-Type: application/json" -X POST -v -u myuser:mypass
    

    【讨论】:

    • 我有内联版本$body_j="{`"user`":`"ti`",`"pass`":`"passw`"}",然后是Invoke-WebRequest -Uri http://localhost:5000/login -Method Post -Body $body_j -ContentType 'application/json',得到Invoke-WebRequest : SyntaxError: Unexpected token \ in JSON at position 1
    • @Timo,我在你的命令中没有看到任何\ ,所以我没有解释,但请注意这个问题是关于curl.exe,而不是Invoke-WebRequest cmets 不适合进行故障排除,因此我鼓励您提出新问题
    【解决方案2】:

    我认为我们可以使用 here-string 作为 Invoke-RestMethod 的 json 主体,如下所示

    $bufferTime = 5
    $requestBody = @"
    {
    "size": 0,
        "aggs": {
        "last_x_min": {
            "filter": {
            "range": {
                "@timestamp": {
                "gte": "now-$($bufferTime)m",
                "lte": "now"
                }
            }
            },
            "aggs": {
            "value_agg": {
                "avg": {
                "field": "time-taken"
                }
            }
            }
        }
        }
    }
    "@
    
    $esResponse = Invoke-RestMethod -URI http://locahost:9200 -TimeoutSec 15 -Method Post -ContentType 'application/json' -Body $requestBody
    

    这是我用来查询 Elasticsearch 的脚本。无需转义双引号。

    【讨论】:

    • 这在没有 \ -escaping 嵌入的 " 实例的情况下工作,因为您正在调用 cmdlet(PowerShell 原生命令,Invoke-RestMethod)而不是外部实用程序(例如在 OP 的情况下为 curl)。虽然我希望这两个调用场景不需要不同的引用,但不幸的是它们需要。
    猜你喜欢
    • 2021-06-29
    • 2018-09-02
    • 2018-05-28
    • 1970-01-01
    • 2016-03-29
    • 1970-01-01
    • 2021-01-24
    • 2012-04-27
    • 2021-11-21
    相关资源
    最近更新 更多