I am trying to send a post request using curl command in shell script.
When i run this curl command in terminal, it is working fine.
curl -d '{"DataArr":[{"serialno":"ab1","filePath":"/home/name/notes1"}]}' -H 'Content-Type: application/json' -H 'Authorization: tasfdgfdhh...' http://localhost:8081/create
The same I am trying to run this as shell script file, it is hitting the server but the data format is not expected. The array bracket is converting as :" or something like :{ . I tried so many times with different possibilities but i do not understand how to prepare correct request. Below is the code and the response at server side.
I am using looping statement to simulate multiple requests,
code:
#!/bin/bash
echo "hello welcome to testing";
token=asdghadjakalskl.....
requestNo=10
i=0
sNo=(ab1 ab2 ab3 ab4 ab5)
fn=(notes1 Pictures/crop.jpeg Pictures/cat.jpeg Pictures/mountain.jpg Pictures/magic.jpeg Pictures/tree.jpg)
echo $1
for (( i=0; i< $1;i ))
do
# echo "welcome inside the loop $s"
echo ${sNo[i%5]} ${fn[i%6]}
f="/home/name/${fn[i%6]}"
# echo $token
echo file $f
echo $i request sent
curl -d '{"DataArr":[{"serialno":'${sNo[i%5]}',"filePath":'$f'}]}' -H "'Content-Type: application/json'" -H 'Authorization: '$token'' http://localhost:8080/create
done
At server side,
{"{\"qualityDataArr\":":{"{\"serialNumberCustomer\":ab1,\"filePath\":/home/name/notes1}":""}}
Please guide me. Thank you!
CodePudding user response:
Try echo """'{\"DataArr\":[{\"serialno\":\"${sNo[i%5]}\",\"filePath\":\"$f\"}]}'"""
and if it displays well, then use echo curl -d """'{\"DataArr\":[{\"serialno\":\"${sNo[i%5]}\",\"filePath\":\"$f\"}]}'""" -H "'Content-Type: application/json'" -H """'Authorization: $token'""" http://localhost:8080/create | bash
CodePudding user response:
There are some issues with the curl
command here that I would prefer to approach slightly differently.
The first issue is the preparation of the JSON.
With '{"DataArr":[{"serialno":'${sNo[i%5]}',"filePath":'$f'}]}'
, the resulting JSON has a problem. The values for serialno
and filePath
looks likely alphanumeric or may contain spaces, meaning the values would need to be double quoted, eg "filePath": "/path/to/some where/to/new note"
, and this is not handled.
I would suggest to prepare the JSON using jq
and store in a shell variable for later use with curl -d
. Example,
jq --null-input \
--arg serialno ${sNo[i%5]} \
--arg filePath $f \
'{"DataArr": [{"serialno": $serialno,"filePath": $filePath}]}'
--null-input
is used because we wants to construct JSON data from scratch
--arg name value
allows us to pass a string value to jq
as a predefined variable.
This will for example gives you the following well formed JSON:
{
"dataarr": [
{
"serialno": "ab1",
"filepath": "/home/name/notes1"
}
]
}
And this well formed JSON can be stored in a shell variable for later use:
prepared_payload=$( jq --null-input \
--arg serialno ${sNo[i%5]} \
--arg filePath $f \
'{"DataArr": [{"serialno": $serialno,"filePath": $filePath}]}' )
Now we can use this prepared_payload
, like curl -d "${prepared_payload}"
The next issue is the inappropriate usage of single and double quotes in curl
header options -H "'Content-Type: application/json'"
and -H 'Authorization: '$token''
There are related past questions/answers, that can be helpful to take a deeper look at,
Difference between single and double quotes in Bash https://www.gnu.org/software/bash/manual/html_node/Single-Quotes.html https://www.gnu.org/software/bash/manual/html_node/Double-Quotes.html
The preferred approach would be -H "Content-Type: application/json"
and -H "Authorization: $token"
The end curl
command would thus looks as follows:
prepared_payload=$( jq --null-input \
--arg serialno ${sNo[i%5]} \
--arg filePath $f \
'{"DataArr": [{"serialno": $serialno,"filePath": $filePath}]}' )
curl -d "${prepared_payload}" -H "Content-Type: application/json" \
-H "Authorization: $token" \
http://localhost:8080/create