Reputation: 91
Using bash v4.3.48(1) on Ubuntu 16.04.2 LTS and bash v3.2.57 on macOS Sierra 10.12.5 I have this code which POSTs JSON data stored in a variable:
#1
JSON_DATA="Test"; \
curl -X POST "https://www.techotaku.com/json.php" \
-H "Content-Type: application/json" \
-d '{"data":"'$JSON_DATA'"}'
This returns:
Array
(
[data] => Test
)
However, if $JSON_DATA contains a space...
#2
JSON_DATA="A Test"; \
curl -X POST "https://www.techotaku.com/json.php" \
-H "Content-Type: application/json" \
-d '{"data":"'$JSON_DATA'"}'
...it throws an error:
curl: (3) [globbing] unmatched close brace/bracket in column 6
I thought this might be due to incorrect use of quotes, but if I echo the JSON data...
echo '{"data":"'$JSON_DATA'"}'
...it appears well-formed:
{"data":"A Test"}
Also, if I include the JSON data as a string and not a variable, it works.
#3
curl -X POST "https://www.techotaku.com/json.php" \
-H "Content-Type: application/json" \
-d '{"data":"A Test"}'
The only way I can get it to work if the variable contains a space is to enclose the JSON data in double-quotes and escape the literal double-quotes in the string:
#4
JSON_DATA="A Test"; \
curl -X POST "https://www.techotaku.com/json.php" \
-H "Content-Type: application/json" \
-d "{\"data\":\"$JSON_DATA\"}"
I would have thought that all 4 examples would have worked. So, can anyone throw any light on why only examples 1,3 and 4 work and example 2 doesn't?
Many thanks, Steve.
Upvotes: 2
Views: 4836
Reputation: 18687
You should quote your variables to prevent word splitting by shell. Your second example:
'{"data":"'$JSON_DATA'"}'
doesn't work because it's being expanded by bash
to two words:
{"data":"A Test"}
so -d
option receives 2 arguments ({"data":"A
and Test"}
). If JSON_DATA
contained globbing metacharacters, those would cause filename expansion.
To fix it, quote it:
'{"data":"'"$JSON_DATA"'"}'
Note the use of alternating single and double quotes. This will be expanded to a single word:
{"data":"A Test"}
Here's a more detailed answer I wrote some time ago which also mentions another convenient option, the use of a here-document.
Upvotes: 6