Curl not accepting spaces in script via variables

Hi All,

I'm trying to run a script which issues rest commands via curl to an endpoint. If I put spaces in fields via something like insomnia, it works, but when I try from an input file, it's failing with a json error.

while IFS=, read mname oname           <------ my input file is:    Test Name,New Name
do
#echo $mname
....

....


curl --request POST \
  --url http://192.168.0.1:1111/Service2/configuration/v1.0/Endpoint/ \
  --header 'authorization: Bearer '$token   \
  --header 'content-type: application/json' \
  --silent \
  --data '{
        -- "mName": "Test Name",                   <------with this line it works
        "mName": '\"$mname\"',             <-------with this line it fails

The output is

Test Name New Name

{"message":"JSON parse error","statusCode":400}

If I echo in from on curl, I get:

 --header content-type: application/json --silent --data {
       "mName": "Test Name",
        "oName": "New Name",

so it looks to be correct - just that without the echo, I get the error.

Any ideas?

Most shells don't expand variables within single quotes. Try

"mName": "$mname", 

You may have missed the quote in data.

--data '{

If I remove that (and the quote at the end), and then put

"mName": "$mname",

I get

./addclients.sh: line 20: mName: command not found

:frowning:

I have to have the start/end single quote in the data element, and I need the double quotes around the $mname variable

I've discovered a handy little tool called jq which can be used to build, display and manipulate JSON. If you are on Linux you can probably install it from the repository. Then you could change your curl invocation from

--data '{ 
...
}'

to

--data $(jq -nc --arg mName "$mname" --arg oName "$oname" '{ $mName, $oName }')

Note that the variables inside the braces are jq variables, rather than shell variables, and will expand into

{"mName":"Test Name","oName":"New Name"}

I hope this helps.

Andrew

I'm trying - is there an alternative just in case that doesn't with with our admins?

--data $(printf '{"mName":"%s","oName":"%s"}' "$mname" "$oname")

may work too. Notice how I've used single quotes for the format string to preserve the double quotes without escaping them.

If that does not work try using an interim variable that can be passed as the JSON string.

Andrew

  --data $(printf '{
       "mName": "%s",
...
}
' "$mname")
================

{"message":"JSON parse error","statusCode":400}

:frowning:

What happens if you don't put in all the white space?

--data $(printf '{"mName":"%s","oName":"%s"}' "$mname" "$oname")

Or use an intermediate variable:

json_data=$(printf '{"mName":"%s","oName":"%s"}' "$mname" "$oname")
curl ...
   --data "${json_data}" ...

tried both ways. removed all my white spaces and tried a variable. Here is a better code stub which shows the full data element.

...

json_data=$(printf '{"mName":"%s","oName":"%s","lCode":"%s","schema":[{"name": "Fred","RequestId":"1234","Name":"Test","BO":"999999","aId":"%s","keyId":"p1","eId":"Test.ts"}],"cCode":"%s","cCode2":"GB","Url":{"protocol":"http","host":"test.co.uk","port": 1653,"endpoints":[{"name": "requestorEndpoint","value": "mEP"}]}}' "$mName" "$oName" "$lCode" "$aId" "$cCode")



curl --request POST \
  --url http://192.168.1.12:12345/pSvc/config/ps2Req/ \
  --header 'authorization: Bearer '$token   \               <--------- $token comes from further up in the code.
  --header 'content-type: application/json' \
  --silent \
  --data '${json_data}'             <-------- note I had to use single quotes

done < $infile

Found a working solution here - shell - How can I use a variable in curl call within bash script - Stack Overflow

message="Hello there"
curl -X POST -H 'Content-type: application/json' --data '{"text": "'"${message}"'"}'

Far from elegant, but it works... I will play with jq when I get some time.

1 Like

The goal is to have "quotes" around the text with spaces.
But you must quote these "quotes" to hide them for the shell. Place them inside 'ticks' is one method.
And you must have $variables in "quotes" for the shell - these protective quotes are removed, when passed to the curl.

'{"text": "'"${message}"'"}'

And this is a concatenation of 'string' "string" 'string' where the shell passes stringstringstring to curl.

Moderator comments were removed during original forum migration.