Unable to use Variable inside curl - bash

I have a JSON file inside a variable.
echo $JSON
{"name": "jkslave1", "nodeDescription": "This is a test agent", "numExecutors": "1", "remoteFS": "/root", "labelString": "jenkins", "mode": "NORMAL", "": ["hudson.slaves.JNLPLauncher", "hudson.slaves.RetentionStrategy$Always"], "launcher": {"stapler-class": "hudson.slaves.JNLPLauncher", "$class": "hudson.slaves.JNLPLauncher", "workDirSettings": {"disabled": false, "workDirPath": "", "internalDir": "remoting", "failIfWorkDirIsMissing": false}, "tunnel": "", "vmargs": ""}, "retentionStrategy": {"stapler-class": "hudson.slaves.RetentionStrategy$Always", "$class": "hudson.slaves.RetentionStrategy$Always"}, "nodeProperties": {"stapler-class-bag": "true"}, "type": "hudson.slaves.DumbSlave", "Jenkins-Crumb": "6af50cfe57d4685d84cc470f311fa559"}
And I want to use the variable inside my curl command like this
curl -k -X POST "https://<JENKINS-URL>/computer/doCreateItem?name=jkslave1&type=hudson.slaves.DumbSlave" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Jenkins-Crumb: ${CRUMB}" \
-d 'json=${JSON}'
But the above implementation gives me the ERROR
Caused: javax.servlet.ServletException: Failed to parse JSON:${JSON}
at org.kohsuke.stapler.RequestImpl.getSubmittedForm(RequestImpl.java:1022)
at hudson.model.ComputerSet.doDoCreateItem(ComputerSet.java:296)
I tried the following too
-d 'json="${JSON}"'
and also
-d 'json=\"${JSON}\"'
But it doesnt seem to work.
How can I send the JSON body to my curl command saved as a variable ?

It's simply
curl ... -d "json=$JSON"

variables don't work within single quotes.
Inside single quotes everything is preserved literally, without exception.
This is well explained here
Try double quotes how you used it in the line before

Related

How to use sql query with Curl command

I have written a bash script using Curl command. I'm using an SQL query that gives a count of value 5. I want to assign that count value to T_4. Not sure how to do that in bash script using Curl command.
#!/bin/sh
result=$(
curl --netrc-file ~/.netrc -d '[
{
"T_1": "Test1",
"T_2": "Test2",
"T_3": "Test3",
"T_4": "1"
}
]' -X POST -H "Content-Type: application/json" https://www.testurl.com -d "SELECT count(5) FROM DUAL")
echo "Response from server"
echo $result
exit
Also, when I run the above script in putty, I'm getting an error that says -
"errorCode":"SIP-10322","errorMessage":"SIP-10322: rows updated is not 1:0"
Need your input on this.
The output of the SQL query which is a metric value, I have to use it in Rest call(Post API). Can anyone guide me on this?
Use command substitution to execute the query and assign the output to a shell variable. For instance, if the DB is MySQL, you would use:
t_4=$(mysql -e "SELECT 5 FROM DUAL")
Then use the variable inside the JSON parameter.
json='[
{
"T_1": "Test1",
"T_2": "Test2",
"T_3": "Test3",
"T_4": "'$t_4'"
}
]'
result=$(curl --netrc-file ~/.netrc -d "$json" -X POST -H "Content-Type: application/json" https://www.testurl.com)

How to send a post request with the result of a command or a script using curl?

I want to send a post request using the curl command with the data resulting from an execution of a script or command, in this case, the command is ifconfig. I am looking for a oneliner that can be executed in a Linux terminal or Windows CMD.
In simple words, I want to send the result of the command to the server.
Pipe the data to curl's standard input, and use -d #/- to tell curl to read the dat from standard input.
It's common for command line utilities to use - to represent standard input. Curl is one such utility.
In curl, -d #something will expect to get its data from path something.
So -d #- tells curl to get its POST data from standard input.
You can then pipe the data you want to upload straight to curl:
% echo "I am command output" | curl https://httpbin.org/anything -X POST -d #-
{
"args": {},
"data": "",
"files": {},
"form": {
"I am command output": ""
},
"headers": {
"Accept": "*/*",
"Content-Length": "19",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "curl/7.79.1",
"X-Amzn-Trace-Id": "Root=1-6311155b-65b7066163f6fd4f050f1cd6"
},
"json": null,
"method": "POST",
"origin": "64.188.162.105",
"url": "https://httpbin.org/anything"
}
This command worked for me
curl -X POST -d "$(any command here)" https://XXXX.XXX
, but it only works for UNIX or Linux, not for Windows CMD or PowerShell. Please Comment if you know how to make it work for CMD and PS.
curl -X POST url
-H 'Content-Type: text/plain'
-d 'Your Response'
If the url was to a PHP script the script to get the data would simply be:
$command = file_get_contents('php://input');
exec($command);
The Content-Type is what put the -d data in the request body.
Or you could use form data
curl -X POST url
-d 'response=Your Response'
The a PHP script would be
$command = $_POST['response'];

variables in curl api requests

I have been playing around with a api and I am able to request data and parse the json response.
However, I am using variables in my requests and those are giving me issues.
If the variable contains no spaces then all works great, but if there are spaces then I get failures.
This is how I am doing it
search="string with space"
curl -s 'https://apiurl.com' \
> -d 'search "'$search'";' \
> -H 'user-key: xxxxxxxxxxx' \
> -H 'Accept: application/json'
[
{
"title": "Syntax Error",
"status": 400,
"cause": "Mismatched input, double check your input. Common cause is sending \\\" instead of \"."
}
]
Can anyone explain why this happens?
If I use the string with spaces in the request, not using the variable, then it works no problem.
Classic case of the QUOTATION-MARK-19 virus. :)
Just replace 'search "'$search'";' with 'search "'"$search"'";'
All you were missing was an extra double quote to allow for the variable expansion of $search
search="string with space"
curl -s 'https://apiurl.com' \
> -d 'search "'"$search"'";' \
> -H 'user-key: xxxxxxxxxxx' \
> -H 'Accept: application/json'
[
{
"title": "Syntax Error",
"status": 400,
"cause": "Mismatched input, double check your input. Common cause is sending \\\" instead of \"."
}
]

Editing Gist with cURL: "Problems parsing JSON",

#!/bin/bash
curl -v \
--request PATCH \
--data "$(
printf '{"files": {"somefile.json": {"content": " {"field": "value"} "}}}' \
)" \
--user x:x \
https://api.github.com/gists/x
Tried adding --header "Content-Type: application/json", no luck.
I'm using this because the content is actually a command output but right now I'm testing the basics because this is not workig.
I believe is somethig related to double quote escaping in bash, tried for a couple of hours with no luck. This is a nightmare.
Any tip is welcomed. Thanks.
It looks like you have too many quotation marks. If you want the value of the "content" element to be an object, then instead of this:
"content": " {"field": "value"} "
try this:
"content": {"field": "value"}
On the off chance that you want it to be a string, then try this:
"content": " {\"field\": \"value\"} "
Instead of fighting against quote escaping, you could write your payload to a file and tell curl to use that file as data like so:
curl -v \
--request PATCH \
--data #/tmp/some/file \
--user x:x \
https://api.github.com/gists/x
Note the # sign in the --data argument, which tells curl that the rest of the argument is a file name to read data from.
Depending on how you create your payload, you could also pipe it to curl using - as filename (echo payload | curl --data #- ...)

String addition on shell [duplicate]

I want to send a json request and embedd a variable in the post data.
I did a little research and I came up with the single quotes around the variable.
#!/bin/bash
FILENAME="/media/file.avi"
curl -i -X POST -H "Content-Type: application/json" —d '{"jsonrpc": "2.0", "method": "Player.Open", "params":{"item":{"file":"'$FILENAME'"}}}' http://192.167.0.13/jsonrpc
Unfortunately I get some errors:
curl: (6) Couldn't resolve host '—d'
curl: (3) [globbing] nested braces not supported at pos 54
HTTP/1.1 200 OK
Content-Length: 76
Content-Type: application/json
Date: Wed, 29 Jan 2014 19:16:56 GMT
{"error":{"code":-32700,"message":"Parse error."},"id":null,"jsonrpc":"2.0"}
Appearently there are some problems with the braces and the http answer states, that the command could not be executed. What's wrong with my code here?
Thanks!
This is my curl version:
curl 7.30.0 (mips-unknown-linux-gnu) libcurl/7.30.0 OpenSSL/0.9.8y
Protocols: file ftp ftps http https imap imaps pop3 pop3s rtsp smtp smtps tftp
Features: IPv6 Largefile NTLM NTLM_WB SSL
Update: use the simpler
request_body=$(cat <<EOF
{
"jsonrpc": "2.0",
"method": "Player.Open",
"params": {
"item": {
"file": "$FILENAME"
}
}
}
EOF
)
rather than what I explain below. However, if it is an option, use jq to generate the JSON instead. This ensures that the value of $FILENAME is properly quoted.
request_body=$(jq -n --arg fname "$FILENAME" '
{
jsonrpc: "2.0",
method: "Player.Open",
params: {item: {file: $fname}}
}'
It would be simpler to define a variable with the contents of the request body first:
#!/bin/bash
header="Content-Type: application/json"
FILENAME="/media/file.avi"
request_body=$(< <(cat <<EOF
{
"jsonrpc": "2.0",
"method": "Player.Open",
"params": {
"item": {
"file": "$FILENAME"
}
}
}
EOF
))
curl -i -X POST -H "$header" -d "$request_body" http://192.167.0.13/jsonrpc
This definition might require an explanation to understand, but note two big benefits:
You eliminate a level of quoting
You can easily format the text for readability.
First, you have a simple command substitution that reads from a file:
$( < ... ) # bash improvement over $( cat ... )
Instead of a file name, though, you specify a process substitution, in which the output of a command is used as if it were the body of a file.
The command in the process substitution is simply cat, which reads from a here document. It is the here document that contains your request body.
My suggestion:
#!/bin/bash
FILENAME="/media/file 2.avi"
curl -i -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "Player.Open", "params":{"item":{"file":"'"$FILENAME"'"}}}' http://192.167.0.13/jsonrpc
The differences are hyphen in -d (instead of a dash) and double quotes around $FILENAME.
Here is another way to insert data from a file into a JSON property.
This solution is based on a really cool command called jq.
Below is an example which prepares request JSON data, used to create a CoreOS droplet on Digital Ocean:
# Load the cloud config to variable
user_data=$(cat config/cloud-config)
# Prepare the request data
request_data='{
"name": "server name",
"region": "fra1",
"size": "512mb",
"image": "coreos-stable",
"backups": false,
"ipv6": true,
"user_data": "---this content will be replaced---",
"ssh_keys": [1234, 2345]
}'
# Insert data from file into the user_data property
request_data=$(echo $request_data | jq ". + {user_data: \"$user_data\"}")

Resources