I am quite new to shell scripting.
I have the following script:
out="FAILURE"
curl -X POST -d 'json={"json":"message"}' http://localhost:8888/json.tail.test
I want to replace "message" with the $out's value. I tried different ways but could not get that done. Can someone please suggest me?
Do this:
out="FAILURE"
curl -X POST -d 'json={"json":"'$out'"}' http://localhost:8888/json.tail.test
Basically, enclose everything except $out inside single quotes. Single quotes protect double quotes but suppress the expansion of variables like $out.
Try this:
out="FAILURE" curl -X POST -d 'json={"json": $OUT}' http://localhost:8888/json.tail.test
You just need to literally replace "message" with $OUT
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:
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...
How does one format a string leveraging an environment variable within at the command line? For example, I want to curl and pass some variable, i.e.:
curl -X POST --data-urlencode 'payload={"text": "I want to print an environment variable here, eg a path: $PATH"}' https://someapi.com/
The easy answer is to change the kind of quotes you're using:
curl -X POST --data-urlencode \
'payload={"text": "I want to print an environment variable here, eg a path: '"$PATH"'"}' \
https://someapi.com/
Notably, this is still using single-quotes on the outside (so you don't need to change your payload), but then it ends the single quotes, starts double quotes, and embeds your substitution in those double quotes (before ending them and switching back to single quotes, within which literal -- rather than syntactic -- double quotes can be embedded).
A variant on this approach, which avoids the need for syntactic quotes mixed into the document content, is to used an unquoted heredoc, as advised by #chepner in the comments:
curl -X POST --data-urlencode #- https://someapi.com/ <<EOF
payload={"text": "I want to print an environment variable here, eg a path: $PATH"}
EOF
The better answer is to use a tool that knows how to format JSON; jq is a widely popular choice. Consider the following example:
text="I want to print an environment variable here, eg a path: \"$PATH\""
curl -X POST --data-urlencode #- https://someapi.com/ <<EOF
payload=$(printf '%s\n' "$text" | jq -R '{text: .}')
EOF
This way you're guaranteed valid output, even if your environment variable contains backslashes, literal quotes, nonprintable characters, or whatever else may come.
How can I send a double quote char using curl.exe in the -d parameter. I don't want to URL encode the double quote. Since the -d data needs to be surrounded in double quotes, I cannot seem to get it to work.
Or is there another flag for curl.exe that tells it to use a files contents for the whole form post data?
My curl.exe works with this form:
-d "{\"param\":\"value\"}"
i.e. doublequotes around data, and doublequotes masked with backslash inside
You can most certainly escape double quotes. How you do that depends on your operating system and shell, which you fail to specify. On Windows, you'd use the ^ as the escape character.
You can also do this:
curl [...] -d #filename
...which reads post data from a file called filename.
Google and/or man is your friend.
http://curl.haxx.se/docs/manpage.html
For the escaping of double quote question, I'm finding that tripling the doublequotes works from the shell:
curl -d {"""foo""":"""bar"""}
while doubling the doublequotes works from within a batch file:
curl -d {""foo"":""bar""}
Which is quite annoying for testing in the shell first.
You can surround the data with single quotes and use double quotes inside.
Example in PowerShell
curl.exe https://httpbin.org/anything `
-H 'Content-Type: application/json' `
-d '{ "this": "is proper json" }'.Replace('"', '""')
Please note that cURL is built into Windows 10, but PowerShell shadows it with an alias, so you have to use curl.exe
If you are doing this in Powershell, you will need to quote the whole text block with single quotes and still escape the quotes. i.e. -d '{\"param\":\"value\"}'
Tested on Win11 VSCode Powershell 7 terminal
There is something called dollar slashy string.
def cmd = $/ curl -d '{"param":"value"}' -X POST https://example.com/service /$
sh cmd