多行 JSON 卷曲
Posted
技术标签:
【中文标题】多行 JSON 卷曲【英文标题】:Curl with multiline of JSON 【发布时间】:2016-04-23 05:25:11 【问题描述】:考虑下面的 curl 命令,是否可以在 JSON 中允许换行符(没有缩小)并直接在 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
似乎发生了错误
如何修复上述命令?
更新:实际上我之前能够运行该命令而没有问题,不知道为什么最近会出现问题。
【问题讨论】:
你能告诉我们更多关于错误的信息吗?您的示例在我的系统上“按原样”运行。mymac > bash --version GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15) Copyright (C) 2007 Free Software Foundation, Inc.
是的,也适用于我:GNU bash, version 4.3.42(1)-release
也可以查看ANSI C-like string syntax:echo $'here is a newline:\nand here is a tab:\t'
application/json
是 JSON 数据的正确媒体类型 -- 请参阅 RFC4627
【参考方案1】:
我认为这可以是一个答案
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"
'
【讨论】:
【参考方案2】:我记得 Bash 手册页和 detailed here 中描述的另一种使用“此处文档”的方法。 @-
表示从 STDIN 读取正文,而 << EOF
表示将脚本内容通过管道传输到“EOF”作为 STDIN 卷曲。这种布局可能比使用单独的文件或“回显变量”方法更易于阅读。
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 选项去除了换行符。已更正!)
【讨论】:
这很干净,没有额外的引用,没有转义,而且效果很好。谢谢。 我们可以使用这种语法的管道吗? 是的,您可以将输出通过管道传输到另一个命令,尽管位置就在中间。在标准输入重定向之后添加标准输出重定向。使用字数统计的示例:-d @- << EOF | wc
去除新行的不是 Here Document,而是 curl -d
选项:curl.haxx.se/docs/manpage.html#-d。使用--data-binary
保留换行符和回车符。
可以在 JSON 中插入变量吗?我不这么认为。【参考方案3】:
由于某种原因,这种 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 时围绕它的单个刻度,但不是第二次。
【讨论】:
【参考方案4】:按照 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
缺点很明显(以前有 2 个或多个文件。)但从好的方面来说,你的脚本可以接受文件名或目录参数,你永远不需要编辑它,只需在不同的地方运行它JSON 文件。这是否有用取决于您要完成的工作。
【讨论】:
注意:确保您通过jsonlint.com获得有效的json内容 与其他方法相比,这种方法干净且易于调试。 很好的解决方案。小心 PATH !【参考方案5】:您可以将您的 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 @-
【讨论】:
使用单引号将块括起来意味着您不能在 JSON 中使用变量(例如$username
)。
是的,但是使用双引号意味着您不能在数据中使用 $ 符号。选择适合您的。【参考方案6】:
您应该使用外部双引号,并转义所有内部引号,如下所示:
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 卷曲的主要内容,如果未能解决你的问题,请参考以下文章