用多行JSON进行卷曲


83

考虑下面的curl命令,是否可以在JSON中使用换行符(不使用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 { 如何修复以上命令?”出现了错误。

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


1
您能告诉我们更多有关该错误的信息吗?您的示例在我的系统上按“原样”工作。 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
miken32 '16

1
还要检查类似ANSI C的字符串语法echo $'here is a newline:\nand here is a tab:\t'
miken32 '16

application/json是JSON数据的正确媒体类型-请参阅RFC4627
Pocketsand,

Answers:


120

我记得Bash手册页中已介绍并在此处进行了详细介绍的“此处文档”的另一种处理方法。该@-方法从stdin读取身体,而<< EOF手段来管脚本内容,直到“EOF”作为标准输入到卷曲。与使用单独的文件或“回显变量”方法相比,此布局可能更易于阅读。

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选项可以准确记录导线上的走线。由于某种原因,此“此处文档”方法剥离了换行符。(更新:换行符由curl -d选项剥离。已更正!)


5
这很干净,没有多余的引号,没有转义,并且效果很好。谢谢。
赛斯

我们可以使用具有这种语法的管道吗?
伊万·巴拉索夫

2
是的,您可以将输出通过管道传递到另一个命令,尽管该位置恰好在中间。在标准输入重定向之后添加标准输出重定向。使用字数统计的示例:-d @- << EOF | wc
Eric Bolinger,

2
不是在这里删除新行,而是curl -d选择:curl.haxx.se/docs/manpage.html#-d。使用--data-binary保持换行符和回车符。
dzieciou

35

按照马丁关于将JSON放入变量中的建议,您还可以将JSON放入单独的文件中,然后-d使用curl的@语法提供文件名:

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文件上运行它即可。这是否有用取决于您要完成的工作。


1
注意:请确保您通过jsonlint.com
vikramvi

与其他方法相比,此方法干净且易于调试。
vikramvi '18

很好的解决方案。小心PATH!
皮埃尔·费里

20

您应该使用外部双引号,并使用所有内部引号进行转义,如下所示:

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\"
    }
}"

19

您可以将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 @-

使用单引号将块引起来意味着您不能${username}在JSON中使用变量(例如)。
航空

是的,但是使用双引号意味着您不能在数据中使用$符号。选择最适合您的一个。
Martin Konecny

19

由于某种原因,此“此处文档”方法剥离换行符

@ 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的单笔交易,但第二次没有。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.