Home > Mobile >  bash script looks right but giving "Unexpected end of JSON" / "curl error (3): unmatc
bash script looks right but giving "Unexpected end of JSON" / "curl error (3): unmatc

Time:08-04

I want my bash script to take some input and use it in the body of a cURL POST. Here is how it looks:

function testBashImport() {
    clientPath="/Users/sunny/Desktop/Projects/myDir"
    cd $clientPath/app/package
    filePath=`readlink -f *.zip`
    echo "Please add a release note:"
    read releaseNote
    while [ "$releaseNote" = "" ]
    do echo ""
    echo "IT IS REQUIRED TO ADD A RELEASE NOTE!!!"
    echo "Please add a release note:"
    read releaseNote
    done

    echo "Please wait..."
    curl -X --location --request POST 'http://localhost:3030/file-manager/uploadFile' \
--header 'Authorization: Basic someAuthKey==' \
--header 'Cookie: connect.sid=s%some.header%key%here' \
--form 'fileData=@"'$filePath'"' \
--form 'data="{\"releaseNotes\": \"'$releaseNote'\"}"'

    echo ""
}
export -f testBashImport

The script seems to work when releaseNote is one word like i.e. hello or lskdjf

MAC-K03NF:package user$ testBashImport
Please add a release note:
hello
Please wait...
{"status":"success"}

But when I use the same script and make releaseNote more than one word i.e. hello world or kdsfl sldfk sd It fails with some errors:

MAC-K03NF:package user$ testBashImport
Please add a release note:
hello hi hey world
Please wait...
Unexpected end of JSON input
curl: (6) Could not resolve host: hi
curl: (6) Could not resolve host: hey
curl: (3) unmatched close brace/bracket in URL position 8:
world\"}"

Notes:

-The API endpoint works when I use postman

-I've hidden the basic auth stuff

-I have to use --form because I have to send a file as part of the body

Any help is appreciated. Thank you!

CodePudding user response:

Probably a quoting issue.

Looking at this line here and adding some comments to help parse the quoting state:

#      open quote                  close quote  open  close
#      |                           |            |     | 
#      V                           V            V     V
--form 'data="{\"releaseNotes\": \"'$releaseNote'\"}"'

Because releaseNote is not quoted at all, if there is whitespace inside of it then that will trigger Word Splitting when Bash parses the command. So while you wanted Bash to see this as one argument:

data="{\"releaseNotes\": \"hello hi hey world\"}"

Bash is splitting on that whitespace and creating four arguments: data="{\"releaseNotes\": \"hello, hi, hey, and world\"}". And that just doesn't work for this command.

So simply put: Surround $releaseNote in double quotes here.

--form 'data="{\"releaseNotes\": \"'"$releaseNote"'\"}"'

  • Related