Powershell 和 Curl - 在单引号 JSON 正文中使用变量

问题描述 投票:0回答:2

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

$Firstname = "Test"
$Lastname = "User"
$email= '[email protected]'   
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
2个回答
13
投票

尝试以下操作:

$Firstname = "Test"
$Lastname = "User"
$email= '[email protected]'   
$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 的 own 语法而进行转义),同时仍可扩展变量引用 - 请参阅 在线文档
Get-Help about_Quoting_Rules

您清楚地意识到-不幸的是-额外需要

\
-转义
"
实例
-更新PowerShell(核心)7_v7.3++中不再需要;请参阅这个答案 - 但只是为了解释为什么需要这样做:

将参数传递给外部程序时,PowerShell 在进行自身的解析和插值之后,会将包含空格的结果参数用双引号 (

"..."
) 括起来,同时将它们连接起来形成要启动的进程命令行外部实用程序与。不幸的是,它这样做没有转义任何嵌入
"
字符,这实际上导致它们被丢弃;保存它们的唯一方法是
\
-转义它们 - 请参阅 这个答案 了解更多信息。

如果您想与常规双引号字符串内联执行此操作,则必须转义 PowerShell 的

"
实例 too(如
`"
),从而导致尴尬的组合
\`"
:

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

事后思考

Ryan 本人在评论中指出,使用 hashtable 构建数据,然后使用

ConvertTo-Json
将其转换为 JSON 并将其提供给
curl
通过 stdin 是一种替代方案,避免了引用头痛

# Create data as PS hashtable literal.
$data = @{ user = @{ name = "$Firstname $Lastname"; email = "[email protected]" } }

# 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

1
投票

我认为我们可以使用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 的脚本。无需转义双引号。

© www.soinside.com 2019 - 2024. All rights reserved.