bashshellcurl

How can I use a variable in a curl call within a Bash script?


I have this simple task, and I've spent a few hours already trying to figure out how can I use a variable inside a curl call within my Bash script:

message="Hello there"
curl -X POST -H 'Content-type: application/json' --data '{"text": "${message}"}'

This is outputting ${message}, literally because it's inside a single quote. If I change the quotes and put a double quote outside and a single quote inside, it says:

command not found: Hello

and then

command not found: there.

How can I make this work?


Solution

  • Variables are not expanded within single quotes. Rewrite using double quotes:

    curl -X POST -H 'Content-type: application/json' --data "{\"text\": \"${message}\"}"
    

    Just remember that double quotes within double quotes have to be escaped.

    Another variation could be:

    curl -X POST -H 'Content-type: application/json' --data '{"text": "'"${message}"'"}'
    

    This one breaks out of the single quotes, encloses ${message} within double quotes to prevent word splitting, and then finishes with another single-quoted string. That is:

    ... '{"text": "'"${message}"'"}'
        ^^^^^^^^^^^^
        single-quoted string
    
    
    ... '{"text": "'"${message}"'"}'
                    ^^^^^^^^^^^^
                    double-quoted string
    
    
    ... '{"text": "'"${message}"'"}'
                                ^^^^
                                single-quoted string
    

    However, as the other answer and @Charles Duffy pointed out in a comment, this is not a robust solution, because literal " and other characters in $message may break the JSON content.

    Use the other solution, which passes the content of $message to jq in a safe way, and jq takes care of correct escaping.