带有JSON数据的卷曲帖子失败

时间:2017-03-24 02:12:39

标签: json bash curl

我试图使用heredoc来传递我需要通过curl发出POST请求的ONE参数,这是我遇到的错误

./scripts/etcd.sh: line 10: warning: here-document at line 10 delimited by end-of-file (wanted `EOF{peerURLs:[http://etcd-$ordinal:2380]}EOF')
./scripts/etcd.sh: line 9: warning: here-document at line 9 delimited by end-of-file (wanted `EOF{peerURLs:[http://etcd-$ordinal:2380]}EOF')
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    42  100    42    0     0  12639      0 --:--:-- --:--:-- --:--:-- 21000
{"message":"unexpected end of JSON input"}

脚本中触发它的2行

request_body=$(cat <<EOF{\"peerURLs\":[\"http://etcd-$ordinal:2380\"]}EOF); 
curl http://etcd-0.etcd:2379/v2/members -XPOST -H \"Content-Type: application/json\" --data \"$request_body\";

在问自己的问题之前,我已在Using curl POST with variables defined in bash script functions尝试了所有答案。

修改

从下面的答案和评论中我试过

curl http://etcd-0.etcd:2379/v2/members -XPOST -H \"Content-Type: application/json\" --data @<(cat <<EOF\n{\"peerURLs\":[\"http://etcd-$ordinal:2380\"]}\nEOF)

它有效,但是给出了类似的错误

./scripts/etcd.sh: line 12: warning: here-document at line 10 delimited by end-of-file (wanted `EOF')
./scripts/etcd.sh: line 12: warning: here-document at line 10 delimited by end-of-file (wanted `EOF')
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
{"id":"a473da4d8f77b2b0","name":"","peerURLs":["http://etcd-3.etcd:2380"],"clientURLs":[]}

1 个答案:

答案 0 :(得分:1)

尝试:

request_body="{\"peerURLs\":[\"http://etcd-$ordinal:2380\"]}"

Here-docs<<EOF\n ... \nEOF):

  • 本质上是多行构造(因为你的不是,你得到警告)

  • 将其内容发送到 stdin

在您的情况下,不需要任何方面,其中单行可扩展字符串("...")就足够了。

此外,您在curl命令中使用引用的方式已被破坏 - 请参阅底部。

如果您确实想要使用带变量的here-doc ,这是最有效的习惯用法:

read -d '' -r request_body <<EOF
{"peerURLs":["http://etcd-$ordinal:2380"]}
EOF

注意:此处的结算分隔符EOF必须独立在行的最开始(不允许前导空格),  和没有其他字符可以跟随,甚至没有空白和评论。

read用于读取here-doc的内容,通过stdin(-d ''确保整个here-doc作为一个整体读取,-r用于确保读取内容时不解释嵌入的\字符。)

正如您所看到的,这里的优势在于无需转义嵌入式"字符。为\"

chepner指出,您通常可以直接使用here-docs ,而无需辅助变量;在这种情况下,@-作为--data参数告诉curl从stdin读取:

curl http://etcd-0.etcd:2379/v2/members -XPOST -H 'Content-Type: application/json' \
  --data @- <<EOF
{"peerURLs":["http://etcd-$ordinal:2380"]}
EOF

上面的命令还显示了如何正确引用-H选项参数:使用非转义单引号生成字符串 literal 。相比之下,\"Content-Type: application/json\"会创建 2 参数,"Content-Type:application/json" - \"变成 embedded {{ 1}}字符。

同样,要使用"变量而不是here-doc,请使用$request_body而不是"$request_body"