Reputation: 11365
I'm trying to use a heredoc to pass in the ONE param I need to make a POST request via curl, this is the error I run into
./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"}
And the 2 lines in the script that trigger it
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\";
I've tried all the answers here Using curl POST with variables defined in bash script functions before asking my own question.
Edit:
From the answers and comments below I've tried
curl http://etcd-0.etcd:2379/v2/members -XPOST -H \"Content-Type: application/json\" --data @<(cat <<EOF\n{\"peerURLs\":[\"http://etcd-$ordinal:2380\"]}\nEOF)
And it works, but with giving a similar error
./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":[]}
Upvotes: 1
Views: 3458
Reputation: 437953
Try:
request_body="{\"peerURLs\":[\"http://etcd-$ordinal:2380\"]}"
Here-docs (<<EOF\n ... \nEOF
):
are inherently multi-line constructs (because yours isn't, you're getting the warning)
send their contents to stdin.
Neither aspect is required in your case, where a single-line, expandable string ("..."
) is sufficient.
Additionally, the way you use quoting in your curl
command is broken - see bottom.
If you did want to use a here-doc with a variable, this is the most efficient idiom:
read -d '' -r request_body <<EOF
{"peerURLs":["http://etcd-$ordinal:2380"]}
EOF
Note: The closing delimiter, EOF
here, must be on its own line, at the very start of the line (no leading whitespace allowed),
and no other characters may follow, not even whitespace and comments.
read
is used to read the here-doc's contents, via stdin (-d ''
ensures that the entire here-doc is read as a whole, and -r
is used to ensure that the content is read without interpretation of embedded \
chars.)
As you can see, the advantage here is that there's no need to escape embedded "
chars. as \"
.
chepner points out that often you can use here-docs directly, without the need for an auxiliary variable; in this case, @-
as the --data
argument tells curl
to read from stdin:
curl http://etcd-0.etcd:2379/v2/members -XPOST -H 'Content-Type: application/json' \
--data @- <<EOF
{"peerURLs":["http://etcd-$ordinal:2380"]}
EOF
The above command also shows how to quote the -H
option-argument correctly: using unescaped single-quoting to produce a string literal. By contrast, \"Content-Type: application/json\"
would create 2 arguments, "Content-Type:
and application/json"
- with \"
turning into embedded "
chars.
Similarly, to use your $request_body
variable instead of a here-doc, use "$request_body"
rather than \"$request_body\"
.
Upvotes: 4