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 double outside and single inside, it says command not found: Hello and then command not found: there.
How can I make this work?
Let us say you want to pass shell variable $name in the data option -d of cURL command. There are two ways to do this. First is to put the whole argument in double quotes so that it is expandable but in this case, we need to escape the double quotes by adding backslash before them.
The Curl language naming conventions for variables suggest using lowercase letters and a hyphen to join multiple words (for example, variable-name). is the data type of the variable. Specify any valid data type. type is required if value is not specified.
A pretty good rule of thumb is to put double quotes around any variable you want to expand like curl "$header" -w "http code: %{http_code}\\n" -X POST -d "$BODY" "$URL" . Bash always expands $SOMETHING variables if they appear on their own, or if they appear in double quotes. (Not if they appear in single quotes).
In this chapter, we will learn how to use Shell variables in Unix. A variable is a character string to which we assign a value. The value assigned could be a number, text, filename, device, or any other type of data. A variable is nothing more than a pointer to the actual data.
Let’s write a Bash script called http_response.sh that writes the output of the cURL command to a variable and then prints the value of the variable to the shell: When we run the script we get the HTTP response code back: Integrate cURL into a basic Bash script that can be enhanced based on your requirements.
Often, we want to get the response code for a curl request in bash. To do this, we would need to first request the headers of a response and then extract the response code. Here is what it would look like. My site is up. Great! Now let’s move on to making posts with curl in bash scripts.
Also, if you want to automate multiple calls to an API via curl in your Bash shell scripts you will have to use a while loop. At the same time you will also find useful knowing about the Bash sleep command that will allow you to control the amount of calls performed against an API in a certain period of time.
The cURL command can be used in Linux in many different ways (e.g. to download files ). Here we will use cURL to retrieve weather information for London via the Open Weather API. The sample API URL we want to call is: The response we get is in JSON format:
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
While the other post (and shellcheck) correctly points out that single quotes prevent variable expansion, the robust solution is to use a JSON tool like jq
:
message="Hello there"
curl -X POST -H 'Content-type: application/json' \
--data "$(jq -n --arg var "$message" '.text = $var')"
This works correctly even when $message
contains quotes and backslashes, while just injecting it in a JSON string can cause data corruption, invalid JSON or security issues.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With