1

Total noob in BASH. Trying to learn. I have the following bash script to make an API request:

#!/bin/bash
if [ $1 = "new_event" ]; then
    a='https://www.googleapis.com/calendar/v3/calendars/'
    b=$2
    c='/events?access_token='
    d=$3
    path=$a$b$c$d

    echo $4

  OUTPUT="$(curl -s -H "Content-Type: application/json" $path -d $4 )"
  echo "${OUTPUT}"
fi

Positional arguments are 'new_event', calendarId, access token and json string. If I run the script I get:

  • first echo is the json string I pass as parameter in the call:

    ' {"guestsCanSeeOtherGuests": false, "location": "", "description": "TEST", "reminders": {"useDefault": false}, "start": {"dateTime": "2017-07-06T14:00:00", "timeZone": "America/Sao_Paulo"}, "end": {"dateTime": "2017-07-06T15:00:00", "timeZone": "America/Sao_Paulo"}, "guestsCanInviteOthers": false, "summary": "TEST", "status": "tentative", "attendees": []} '
    
  • second echo gives me parsing error.

BUT, if I copy the echoed json string and replace $4 for it, everything works.

OUTPUT="$(curl -s -H "Content-Type: application/json" $path -d ' {"guestsCanSeeOtherGuests": false, "location": "", "description": "TEST", "reminders": {"useDefault": false}, "start": {"dateTime": "2017-07-06T14:00:00", "timeZone": "America/Sao_Paulo"}, "end": {"dateTime": "2017-07-06T15:00:00", "timeZone": "America/Sao_Paulo"}, "guestsCanInviteOthers": false, "summary": "TEST", "status": "tentative", "attendees": []} ' )"

Any hint why is it not working with the positional argument while it works if I paste it's content?

Thanks!

2
  • What is variable $4? It seems non-existent from the looks of it ... Commented Jul 7, 2017 at 22:21
  • Variable $4 is the forth positional argument i'm sending when i call the script, which is the json string. Commented Jul 7, 2017 at 22:25

1 Answer 1

2

When you pass the JSON string as a parameter, it assigns the content contained inside the single quote as a whole string but when you pass it to curl it was subjected to word splitting.

To show what it looks like here's a sample script to demonstrate it.

This script will receive the string and pass it to the second script.

#!/bin/bash
./params $1

This second script simulates what curl sees. It will print the number of parameters it receives.

#!/bin/bash
echo $#

Guess what the output is:

27

To fix your issue and make it simpler, drop the outermost quote and quote everything inside the $().

OUTPUT=$(curl -s -H "Content-Type: application/json" "$path" -d "$4" )
Sign up to request clarification or add additional context in comments.

3 Comments

Hi. Thanks for answering. I am still trying to understand the behavior you mentioned. 27 is a very surprising result for a me (as a newbie). Yet, quoting the $4 didn't work out. Same behavior. I`ll try to get more detailed error adding parameters to curl.
My only guess is you are incorrectly quoting it. bash can't handle nested quote properly. You will need to post what you tried and the output when you run in verbose.
You are absolutely correct, my friend. I`ve used single quotes instead of double. Now I'll work on understanding what happened. :) Thank you very much for your time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.