带有多行 JSON 的 Curl

考虑下面的 curl 命令,是否可以允许在 JSON 中使用 newline (不使用 minify)并直接在 bash (Mac/Ubuntu)中执行

curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
-d \
'
{
"field1": "test",
"field2": {
"foo": "bar"
}
}'

当我运行上面的命令时,似乎在 second {发生了错误 如何修复上述命令?

更新 : 实际上我以前能够运行命令而没有问题,不知道为什么最近发生了问题。

115920 次浏览

您应该使用外双引号,并且转义所有内引号如下:

curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
-d \
"
{
\"field1\": \"test\",
\"field2\": {
\"foo\": \"bar\"
}
}"

您可以将 json 分配给 var:

json='
{
"field1": "test",
"field2": {
"foo": "bar"
}
}'

现在您可以使用 stdin将其转发到 curl:

echo $json | curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
-d @-

根据 Martin 的建议,将 JSON 放在一个变量中,您也可以将 JSON 放在一个单独的文件中,然后使用 curl 的@语法将文件名提供给 -d:

curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
-d @myfile.json

缺点是显而易见的(在过去有一个或多个文件的地方有一个)但是从好的方面来看,脚本可以接受文件名或目录参数,而且不需要编辑它,只需在不同的 JSON 文件上运行它。这是否有用取决于你想要完成什么。

我记得另一种方法是使用 Bash 手册页和 详细资料在此中描述的“ Here Document”。Abc0意味着从 STDIN 读取主体,而 abc1意味着通过管道将脚本内容传送到作为 STDIN 的“ eOF”。这种布局可能比使用单独的文件或“ echo a variable”方法更容易阅读。

curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: application/json; charset=utf-8' \
--data-binary @- << EOF
{
"field1": "test",
"field2": {
"foo": "bar"
}
}
EOF

注意: 使用 --trace <outfile> curl 选项来记录 没错通过导线的内容。由于某种原因,这种 Here Document 方法去掉了换行。(更新: 通过 curl-d 选项删除新行。纠正!)

由于某种原因,这种 Here Document 方法去掉了换行

@ eric-bolinger Heredoc 删除新行的原因是你需要引用 EOF 来告诉你的 Heredoc 保留新行:

curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
-d @- <<'EOF'


{
"field1": "test",
"field2": {
"foo": "bar"
}
}
EOF

注意第一次定义 EOF 时,EOF 周围的单个刻度,而不是第二次。

我觉得这就是答案

curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
--data-raw '
{
"field1": "test",
"field2": {
"foo": "bar"
}
}'