Trouble with bash shell script, attempting to POST variable JSON data using cURL

29,249

You just need to use ' and " escape properly:

now=$(date +"%m-%d-%Y")
curl -X POST -H "Content-Type: application/json" \
    --data '{ "color":"red", "message":"Build failed '"$now"'", "message_format":"text" }' \
    https://api.hipchat.com/v2/room/<room>/notification?auth_token=<token>

or alternatively:

now=$(date +"%m-%d-%Y")
curl -X POST -H "Content-Type: application/json" \
    --data "{ \"color\":\"red\", \"message\":\"Build failed $now\", \"message_format\":\"text\" }" \
    https://api.hipchat.com/v2/room/<room>/notification?auth_token=<token>

Wrapping variables in ' will make bash treat them literally whereas using " will make them replaced by the variable's value

Share:
29,249
Davey Johnson
Author by

Davey Johnson

Updated on July 05, 2022

Comments

  • Davey Johnson
    Davey Johnson almost 2 years

    I'm having trouble with a bash shell script, attempting to POST variable JSON data using cURL. I'm running from a Mac. I can successfully post static data but I can't seem to figure out how to incorporate variables.

    I introduced <room> and <token> for the sake of these examples.

    This script works successfully:

    #!/bin/bash
    curl -X POST -H "Content-Type: application/json" --data '{ "color":"red", "message":"Build failed", "message_format":"text" }' https://api.hipchat.com/v2/room/<room>/notification?auth_token=<token>
    

    Now, I would like to introduce a formatted date. This script posts successfully, but the "$now" is posted literally: i.e. "Build failed $now" rather than "Build failed 10-28-2014"

    #!/bin/bash
    now=$(date +"%m-%d-%Y")
    curl -X POST -H "Content-Type: application/json" --data '{ "color":"red", "message":"Build failed $now", "message_format":"text" }' https://api.hipchat.com/v2/room/<room>/notification?auth_token=<token>
    

    I attempted to format the JSON payload with printf like so. The date string is replaced properly. However, this fails with an error: "The request body cannot be parsed as valid JSON: No JSON object could be decoded: line 1 column 0 (char 0)" - so it seems like I'm misusing $payload.

    #!/bin/bash
    now=$(date +"%m-%d-%Y")
    payload=$(printf "\'{\"color\":\"red\",\"message\":\"Build failed %s\",\"message_format\":\"text\"}\'" $now)
    curl -X POST -H "Content-Type: application/json" --data $payload https://api.hipchat.com/v2/room/<room>/notification?auth_token=<token>
    

    Finally, I attempted to eval the entire command. This fails by hanging and it could be that I'm misusing escapes. I've tried many variations of escaping.

    #!/bin/bash
    now=$(date +"%m-%d-%Y")
    payload=$(printf "\'{\"color\":\"red\",\"message\":\"Build failed %s\",\"message_format\":\"text\"}\'" $now)
    cmd=$(curl -X POST -H \"Content-Type: application\/json\" --data '{\"color\":\"red\",\"message\":\"Build failed $now\",\"message_format\":\"text\"}' https:\/\/api.hipchat.com\/v2\/room\/<room>\/notification?auth_token=<token>)
    eval $cmd
    

    I found this question to be somewhat helpful and I've also read this cURL tutorial. These deal with static data and I think I'm just missing some fundamental bash scripting. Thank you in advance for your help.