Home > OS >  How to send nested object data as post data using curl command in shell script?
How to send nested object data as post data using curl command in shell script?

Time:10-15

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
  • Related