This question already has answers here:
How do I use variables in single quoted strings?
(8 answers)
Closed 6 years ago.
I have a simple function in my bashrc file, it takes 2 arguments and makes a curl call. The problem is, the curl request is not getting the variable. Here's the function...
checkUserName() {
cd ~/
echo "checking for username $2"
curl -w "#curl-format.txt" -H "Content-Type: application/json" -X POST -d '{"userName": "$2"}' http://localhost:8080/$1/verify
}
alias unameCheck=checkUserName
Then I call it with something like...
unameCheck users danwguy
and I will see...
checking for username danwguy
in my terminal prompt, however when I look at my logs from my application it shows that it is checking for userName $2
So the variable isn't being replaced in the curl command, even though the $1 is being replaced, since it is calling the correct API on my localhost.
It replaces it in the echo command, but not in the curl command.
I have even tried creating a local variable, but that still doesn't work, no matter what I do, it doesn't replace in the curl call, but it does in the echo call.
Can anyone see why it wouldn't be properly replacing the $2
Parameter expansions ($var) will not expand in single quotes. Use double quotes instead:
$ curl -w "#curl-format.txt" \
-H "Content-Type: application/json" \
-X POST \
-d '{"userName": "'"$2"'"}' \
"http://localhost:8080/$1/verify"
Also wrap parameter expansions in double quotes to avoid word splitting and
pathname expansion.
Just a note to previous comment.
You can escape double quotes with backslash, to tell bash interpreter to not interpret its special meaning, so final code looks like:
... -d "{\"userName\": \"$2\"}" ...
Which is way more obvious for me...
Related
I'm trying to write a bash script that takes a variable and populates it inside a somewhat complex string and I can't figure out how to get it to work.
I have the following bash code..
PWD="foobar"
curl -XPOST "localhost/api/user/bob" -H 'Content-Type: application/json' -d '{"password" : "${PWD}"}
what I want to have happen is obviously this:
curl -XPOST "localhost/api/user/bob" -H 'Content-Type: application/json' -d '{"password" : "foobar"}
but none of the iterations and expansion "tricks" I know seem to work because of the braces and the single and double quotes.
I've tried
$PWD
${PWD}
Both to no avail.
You need to use double quotes to allow the $PWD to expand. (The braces are irrelevant here.)
-d "{\"password": \"$password\"}"
Better yet, though, use something like jq to generate JSON so that you can be sure everything is quoted correctly without shell interference.
-d "$(jq -n --arg p "$password" '{password: $p}')"
I am trying to write a shell script that invokes two APIs using curl.
One of the keys of JSON output of the first curl is passed to the second curl. In the Bash script below, I am passing token as a command line parameter to the first curl and it works fine.
The output of the first curl is extracted into client_token and I am passing it to the second curl. It is failing.
The reason being, wherever I have $client_token, the value is getting substituted as "value" (with quotes) instead of value (without quotes). Curl expects strings without quotes in the second curl. How can I get rid of double quotes?
echo $1
XVaultToken=`curl -X POST "https://sub.domain.tld:8200/login" -d '{"token":"'"$1"'"}'`
client_token=`echo $XVaultToken|jq '.auth.client_token'
echo $client_token
apiKey=`curl -X GET https://sub.domain.tld:8200/api-key -H 'X-Vault-Token: "'"$client_token"'"'`
#apiKey=`curl -X GET https://sub.domain.tld:8200/api-key -H 'X-Vault-Token: $client_token'`
echo "apikey"
Probably your jq command is outputting the quotes that you don't want. Ask jq for the raw value instead:
client_token=`echo $XVaultToken|jq -r '.auth.client_token'
This question already has answers here:
Command not found error in Bash variable assignment
(5 answers)
Closed 4 years ago.
i'm new to shelling in linux.
i'm trying to write a shell script that uses a REST method and creates some datasources on grafana
i need the url to be modular and to be taken from an argument.
this is the line i'm trying to run:
srv_url = "1.1.1.1:8080"
RESULT=$(/bin/curl --user admin:admin 'http://localhost:3000/api/datasources' -X POST -H 'Content-Type: application/json;charset=UTF-8' --data-binary '{"name":"Events","isDefault":false ,"type":"influxdb","url":"http://$srv_url","access":"proxy","basicAuth":false}')
as you can see i'm trying to plant the variable $srv_url inside ("url":"http://$srv_url"), but it will not take its value, whatever i tried the script uses its literal name, and not its value.
any ideas?
thanks.
Variable substitution in strings only works with double quotes, not single quotes. That means that you'll have to escape all of the quotes in the string or use single quotes:
srv_url = "1.1.1.1:8080"
RESULT=$(/bin/curl --user admin:admin 'http://localhost:3000/api/datasources' -X POST -H 'Content-Type: application/json;charset=UTF-8' --data-binary "{\"name\":\"Events\",\"isDefault\":false ,\"type\":\"influxdb\",\"url\":\"http://$srv_url\",\"access\":\"proxy\",\"basicAuth\":false}")
Alternatively, you could do something like this by ending the single quote string and wrapping the variable in double quotes:
RESULT=$(/bin/curl --user admin:admin 'http://localhost:3000/api/datasources' -X POST -H 'Content-Type: application/json;charset=UTF-8' --data-binary '{"name":"Events","isDefault":false ,"type":"influxdb","url":"http://'"$srv_url"'","access":"proxy","basicAuth":false}')
You can read more about strings and variable substitutions in Bash here.
This question already has answers here:
Difference between single and double quotes in Bash
(7 answers)
Closed 2 months ago.
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?
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.
Use the other solution, which passes the content of $message to jq in a safe way, and jq takes care of correct escaping.
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.
This question already has answers here:
Why does shell ignore quoting characters in arguments passed to it through variables? [duplicate]
(3 answers)
Closed 4 years ago.
I am attempting to do a curl command that uses a predefined variable as a header.
header='-H "Content-Type: application/json" -H "userGUID: 7feb6e62-35da-4def-88e9-376e788ffd97" -H "Content-Length: 51"'
And this is essentially the curl command
curl $header -w "http code: %{http_code}\\n" -X POST -d $BODY $URL
Which then returns the error message
rl: (6) Could not resolve host: application
curl: (6) Could not resolve host: 7feb6e62-35da-4def-88e9-376e788ffd97"
curl: (6) Could not resolve host: 51"
This works as expected
curl -H "Content-Type: application/json" -H "userGUID: 7feb6e62-35da-4def-88e9-376e788ffd97" -H "Content-Length: 51" -w "http code: %{http_code}\\n" -X POST -d $BODY $URL
The reason I'm trying to pass the header as a variable is because I'm writing a script that loops through and array, but currently this does not work with headers for some reason. There is no issue passing arguments for body.
Be aware that variable expansion in bash can catch people off guard easily.
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).
When expanded with double quotes they are treated as a single "token" by the shell, no matter what.
When expanded without double quotes they will be parsed as if you had typed their contents instead of the variable. So - if that variable had spaces, that may mean the shell will treat those as separators between arguments.