【问题标题】:Curl post with JSON data fails带有 JSON 数据的卷发失败
【发布时间】:2017-08-16 20:17:07
【问题描述】:

我正在尝试使用 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"}

以及脚本中触发它的两行

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 尝试了所有答案。

编辑:

从下面我尝试过的答案和 cmets 中

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":[]}

【问题讨论】:

  • Here-docs 不是这样工作的。它的内容必须从新行开始,结束标记必须单独在一行。您的脚本认为 整个事情 (EOF{\"peerURLs\":[\"http://etcd-$ordinal:2380\"]}EOF);) 是您的标记。
  • 您也不想转义引号。 curl -H "Content-Type..." --data "$request_body".
  • 考虑使用像jq 这样的工具来生成您的 JSON,尤其是当您嵌入参数的内容时。

标签: json bash curl


【解决方案1】:

试试:

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

Here-docs(&lt;&lt;EOF\n ... \nEOF):

  • 本质上是多行结构(因为你的不是,所以你会收到警告)

  • 将它们的内容发送到stdin

在您的情况下,这两个方面都不需要,单行可扩展字符串 ("...") 就足够了。

此外,您在 curl 命令中使用引用的方式已损坏 - 见底部。


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

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

注意结束分隔符,此处为EOF,必须单独一行在非常开始行(不允许前导空格), 并且后面不能有其他字符,甚至不能是空格和 cmets。

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

如您所见,这里的优点是无需转义嵌入的" 字符。作为\"


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

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

上述命令还显示了如何正确引用-H 选项参数:使用未转义的单引号生成字符串文字。相比之下,\"Content-Type: application/json\" 将创建 2 个参数,"Content-Type:application/json" - \" 变成 嵌入 " 字符。

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

【讨论】:

  • @Jonathan:听起来您看到了一个不相关的错误。如果您使用bash 在此答案中发布的here-doc,它应该可以工作。另请注意,正如 chepner 已经指出的那样,您的 curl 命令在引用方面被破坏了 - 请参阅我的更新。
  • 我需要引用使用,因为我正在使用 cat 将 bash 命令写入文件,在 kubernetes yaml 文件注释中,其中整个块已经被双引号包围,除此之外我同意你的看法我对 heredocs 仍然非常非常陌生 :)
  • @Jonathan:我明白了——你应该在问题中提到这一点以避免混淆。
猜你喜欢
  • 1970-01-01
  • 2016-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-08
  • 1970-01-01
  • 1970-01-01
  • 2011-04-10
相关资源
最近更新 更多