Bash: Command output as variable to curl error - bash

I trying to get this bash script to run a speedtest (speedtest-cli) then pass the output as a variable to pushbullet via curl.
#!/bin/bash
speed=$(speedtest --simple)
curl --header 'Access-Token: <-ACCESS-TOKEN->' \
--header 'Content-Type: application/json' \
--data-binary {"body":"'"$speed"'","title":"SpeedTest","type":"note"}' \
--request POST \
https://api.pushbullet.com/v2/pushes
Other commands have worked well using this method (eg. whoami) but speedtest and ifconfig just get an error like this:
{"error":{"code":"invalid_request","type":"invalid_request","message":"Failed to decode JSON body.","cat":"(=^‥^=)"},"error_code":"invalid_request"}

Your quoting is wrong:
speed=$(speedtest --simple)
curl --header 'Access-Token: o.4q87SC5INy6nMQZqVHJeymwRsvMXW74j' \
--header 'Content-Type: application/json' \
--data-binary "{\"body\":\"$speed\",\"title\":\"SpeedTest\",\"type\":\"note\"}" \
--request POST \
https://api.pushbullet.com/v2/pushes
Reading from a here document simplifies the quoting:
speed=$(speedtest --simple)
curl --header 'Access-Token: o.4q87SC5INy6nMQZqVHJeymwRsvMXW74j' \
--header 'Content-Type: application/json' \
--data-binary #- \
--request POST \
https://api.pushbullet.com/v2/pushes <<EOF
{ "body": "$speed",
"title": "SpeedTest",
"type": "note"
}
EOF
However, in general you should not assume that the contents of the variable are a properly encoded JSON string, so use a tool like jq to generate the JSON for you.
jq -n --arg data "$(speedtest --simple)" \
'{body: $data, title: "SpeedTest", type: "note"}' |
curl --header 'Access-Token: o.4q87SC5INy6nMQZqVHJeymwRsvMXW74j' \
--header 'Content-Type: application/json' \
--data-binary #- \
--request POST \
https://api.pushbullet.com/v2/pushes
This can be refactored easily:
post_data () {
url=$1
token=$2
data=$3
jq -n --arg d "$data" \
'{body: $d, title: "SpeedTest", type: "note"}' |
curl --header "Access-Token: $token" \
--header 'Content-Type: application/json' \
--data-binary #- \
--request POST \
"$url"
}
post_data "https://api.pushbullet.com/v2/pushes" \
"o.4q87SC5INy6nMQZqVHJeymwRsvMXW74j" \
"$(speedtest ---simple)"

Related

GET CURL doesn't escape some of the characters [duplicate]

This question already has answers here:
Escaping characters in bash (for JSON)
(13 answers)
Parsing JSON with Unix tools
(45 answers)
Closed 10 days ago.
I have the following GET CURL from which I get an xml.
curl -X 'GET' \
'http://local/something/something2' \
-H 'accept: application/json' \
-H 'authorization: auth'
Now I want to use the previous xml received above within this POST CURL:
curl -X 'POST' \
'http://something/something2' \
-H 'accept: application/json' \
-H 'authorization: auth' \
-H 'Content-Type: application/json' \
-d '{
"components": [
{
"locator": "sample",
"config": xml file from above
}
]
}'
How can I make the second CURL with POST?
See this post to see how to capture the output of the first command into a variable. Use it like this:
output=$(curl -X 'GET' \
'http://local/something/something2' \
-H 'accept: application/json' \
-H 'authorization: auth')
# Assuming the $output variable is a JSON object, with a property
# called 'result', use 'jq' to extract the value of that property
result=$(jq -r '.result' <<< "$output")
# As noted above, escape the double quotes with backslashes
curl -X 'POST' \
'http://something/something2' \
-H 'accept: application/json' \
-H 'authorization: auth' \
-H 'Content-Type: application/json' \
-d "{
\"components\": [
{
\"locator\": \"sample\",
\"config\": \"$result\"
}
]
}"
Note the double quotes - double quotes must be there so $output variable can be used. As a result, the double quotes in the JSON need to be escaped.

Use CURL POST using a CURL GET output in bash [duplicate]

This question already has answers here:
Escaping characters in bash (for JSON)
(13 answers)
Parsing JSON with Unix tools
(45 answers)
Closed 10 days ago.
I have the following GET CURL from which I get an xml.
curl -X 'GET' \
'http://local/something/something2' \
-H 'accept: application/json' \
-H 'authorization: auth'
Now I want to use the previous xml received above within this POST CURL:
curl -X 'POST' \
'http://something/something2' \
-H 'accept: application/json' \
-H 'authorization: auth' \
-H 'Content-Type: application/json' \
-d '{
"components": [
{
"locator": "sample",
"config": xml file from above
}
]
}'
How can I make the second CURL with POST?
See this post to see how to capture the output of the first command into a variable. Use it like this:
output=$(curl -X 'GET' \
'http://local/something/something2' \
-H 'accept: application/json' \
-H 'authorization: auth')
# Assuming the $output variable is a JSON object, with a property
# called 'result', use 'jq' to extract the value of that property
result=$(jq -r '.result' <<< "$output")
# As noted above, escape the double quotes with backslashes
curl -X 'POST' \
'http://something/something2' \
-H 'accept: application/json' \
-H 'authorization: auth' \
-H 'Content-Type: application/json' \
-d "{
\"components\": [
{
\"locator\": \"sample\",
\"config\": \"$result\"
}
]
}"
Note the double quotes - double quotes must be there so $output variable can be used. As a result, the double quotes in the JSON need to be escaped.

Echo command not executing in bitbucket pipeline

I am running the following command as a test and finally getting the test result by an API it runs successfully local but final echo command is not executing in bitbucket pipeline ( basically the steps after the while loop )
#! /usr/bin/bash
export token=$(curl -k -XPOST --header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'email=x.x#ifworld.com' \
--data-urlencode 'password=x' \
'https://api.gremlin.com/v1/users/auth?getCompanySession=true?companyName=IFS'\ | jq -r '.[].header')
echo $token
# Add 1 core of CPU load to a random host for 30 seconds
export executionID=$(curl -X POST \
--header "Content-Type: application/json" \
--header "Authorization: $token" \
https://api.gremlin.com/v1/attacks/new?teamId=64582582-6a41-498e-9825-826a41d98e1c \
--data '
{
"command": { "type": "cpu", "args": ["-c", "1", "--length", "30"] },
"target": { "type": "Random" }
}')
echo $executionID
while [[ $(curl -X GET "https://api.gremlin.com/v1/attacks/$executionID?teamId=64582582-6a41-498e-9825-826a41d98e1c" \
--header "Authorization:$token" \
-H "accept: application/json" | jq -r '.stage') != "Successful" ]]
do
if [[ $(curl -X GET "https://api.gremlin.com/v1/attacks/$executionID?teamId=64582582-6a41-498e-9825-826a41d98e1c" \
--header "Authorization:$token" \
-H "accept: application/json" | jq -r '.stage') = "UserHalted" || $(curl -X GET "https://api.gremlin.com/v1/attacks/$executionID?teamId=64582582-6a41-498e-9825-826a41d98e1c" \
--header "Authorization:$token" \
-H "accept: application/json" | jq -r '.stage') = "Failed" || $(curl -X GET "https://api.gremlin.com/v1/attacks/$executionID?teamId=64582582-6a41-498e-9825-826a41d98e1c" \
--header "Authorization:$token" \
-H "accept: application/json" | jq -r '.stage') = "InitializationFailed" || $(curl -X GET "https://api.gremlin.com/v1/attacks/$executionID?teamId=64582582-6a41-498e-9825-826a41d98e1c" \
--header "Authorization:$token" \
-H "accept: application/json" | jq -r '.stage') = "LostCommunication" || $(curl -X GET "https://api.gremlin.com/v1/attacks/$executionID?teamId=64582582-6a41-498e-9825-826a41d98e1c" \
--header "Authorization:$token" \
-H "accept: application/json" | jq -r '.stage') = "ClientAborted" || $(curl -X GET "https://api.gremlin.com/v1/attacks/$executionID?teamId=64582582-6a41-498e-9825-826a41d98e1c" \
--header "Authorization:$token" \
-H "accept: application/json" | jq -r '.stage') = "TargetNotFound" ]]; then
echo "Test Unsuccessful"
break
fi
done
export exec_status=$(curl -X GET "https://api.gremlin.com/v1/attacks/$executionID?teamId=64582582-6a41-498e-9825-826a41d98e1c" \
--header "Authorization:$token" \
-H "accept: application/json" | jq -r '.stage')
echo "Test is $exec_status"

curl set upload chunk size

I want to upload a big file with curl.
For that, I want to split it, without saving it to disk (like with split). I tried to use --continue-at with Content-Length.
curl -s \
--request PATCH \
--header "Content-Type: application/offset+octet-stream" \
--header "Content-Length: ${length}" \
--header "Upload-Offset: ${offset}" \
--continue-at "${offset}" \
--upload-file "${file}" \
"${dest}"
But curl "overshoots" and ignores Content-Length. Is there something like --stop-at? Alternatively, I have to use dd, if necessary.
EDIT
dd solution:
curl -s \
--request PATCH \
--header "Content-Type: application/offset+octet-stream" \
--header "Content-Length: ${length}" \
--header "Upload-Offset: ${offset}" \
--data-binary "#-" \
"${dest}" < <(dd if=${file} skip=${offset} count=${length} iflag=skip_bytes,count_bytes 2>/dev/null)
but if possible I would like to use only cURL..

malformed_path for uploading file into my dropbox

Local spurce file : /tmp/back/wp.bak.sql
Dst file : /
my access token is xxxxxx.
I want to upload the /tmp/back/wp.bak.sql in my local pc into dropbox root directory,and keep the name unchanged.
curl command 1:
curl -X POST https://content.dropboxapi.com/2/files/upload \
--header 'Authorization: Bearer xxxxxx' \
--header 'Content-Type: application/octet-stream' \
--header 'Dropbox-API-Arg: {"path":"/"}' \
--data-binary #'/tmp/back/wp.bak.sql'
Output info.
{"error_summary": "path/malformed_path/...", "error": {".tag": "path", "reason": {".tag": "malformed_path"}, "upload_session_id": ""}}
curl command 2:
cd /tmp/back
curl -X POST https://content.dropboxapi.com/2/files/upload \
--header 'Authorization: Bearer xxxxxx' \
--header 'Content-Type: application/octet-stream' \
--header 'Dropbox-API-Arg: {"path":"/"}' \
--data-binary #'wp.bak.sql'
Same error info.
How to fix the malformed_path for my curl command?
Enter the full path of your file in the path field :
--header 'Dropbox-API-Arg: {"path":"/wp.bak.sql"}'
So :
curl "https://content.dropboxapi.com/2/files/upload" \
-H 'Authorization: Bearer xxxxxx' \
-H 'Content-Type: application/octet-stream' \
-H 'Dropbox-API-Arg: {"path":"/wp.bak.sql"}' \
--data-binary #'wp.bak.sql'
This question previously answers are outdated and not working. Here is a working code which is tested and working perfectly
curl -X POST https://content.dropboxapi.com/2/files/upload \
--header "Authorization: Bearer <your token>" \
--header "Dropbox-API-Arg: {\"path\": \"/file_path.txt\",\"mode\": \"add\",\"autorename\": true,\"mute\": false}" \
--header "Content-Type: application/octet-stream" \
--data-binary "#file_path.txt"

Resources