Parse curl response to variable and use it in curl - bash

I have the following script:
#!/bin/bash
TOKEN=$(curl -isX POST 'http://localhost:3005/auth/tokens' \
-H 'Content-Type: application/json' \
-d '{
"name": "test#test.de",
"password": "1234"
}' | grep X-Subject-Token | sed "s/X-Subject-Token: //g")
echo $TOKEN
curl --trace test.txt -X POST "http://localhost:3005/v1/users" \
-H "Content-Type: application/json" \
-H "X-Auth-token: $TOKEN" \
-d '{
"user": {
"username": "alice",
"email": "alice#test.com",
"password": "test"
}
}'
The command echo $TOKEN is printing the right result (something like 35be3d05-7f80-4b11-ad20-7a7110e9d3a7). From the last curl request I get the following error from curl:
curl: (52) Empty reply from server
If I write above the last curl request TOKEN="35be3d05-7f80-4b11-ad20-7a7110e9d3a7" the request is working. So I guess there is something wrong with the TOKEN variable.
Kindly Regards
EDIT:
Output from declare -p TOKEN :
"eclare -- TOKEN="6770806a-1230-4f64-b519-1841e9deb5f1

I had to remove an carriage return. Thanks to #chepner!
Solution:
TOKEN=$(curl -isX POST 'http://localhost:3005/auth/tokens' \
-H 'Content-Type: application/json' \
-d '{
"name": "test#test.de",
"password": "1234"
}' | grep X-Subject-Token | sed "s/X-Subject-Token: //g" | tr -d '\r')

Related

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.

Pass jq output to curl

I want to be use a number of values from jq piped to curl. I have json data with a structure that looks something like this
{
"apps": {
"code": "200",
"name": "app1",
},
"result": "1"
}
{
"apps": {
"code": "200",
"name": "app2",
},
"result": "5"
}
...
...
...
What I want to do is to take the values of every apps.name and result and pass that to curl:
curl -XPOST http://localhost --data-raw 'app=$appsName result=$result'
The curl command will then run X amount of times depending on how many objects there are.
In jq I came up with this but I don't know how or the best way of passing this to curl in a loop.
jq -r '.result as $result | .apps as $apps | $apps.name + " " + $result myfile.json
Maybe something like this?
jq < data.json '[.apps.name, .result]|#tsv' -r | while read appsName result; do
curl -XPOST http://localhost --data-raw "$appsName $result"
done
jq -r '"\( .apps.name ) \( .result )"' |
while read -r app result; do
curl -XPOST http://localhost --data-raw "app=$app result=$result"
done
or
jq -r '"app=\( .apps.name ) result=\( .result )"' |
while read -r data; do
curl -XPOST http://localhost --data-raw "$data"
done
The first one assumes the name can't contain whitespace.
Would this do it?
while read -r line; do
curl -XPOST http://localhost --data-raw "$line"
done < <(jq -r '"app=\(.apps.name) result=\(.result)"' myfile.json)
I think xargs is better than while loops. Maybe just personal preference.
jq -r '"app=\( .apps.name ) result=\( .result )"' \
| xargs -r -I{} curl -XPOST http://localhost --data-raw "{}"

Curl Multiline on Command Windows 10

How i can send multiline via curl on Windows 10 ?
This is my CURL command :
curl -X POST \
-H "Accept: application/json" \
-H "X-Access-Token: ZmQ780ODRmNDlkMjMzYjA0OTA1Y54545jY5ODQ3MjM0YmNjYjM5ODA1OWU5NTE1YjEwNTdjMjcxMzQ3ZDdjMzMxNDA0ZA==" \
-H "Cache-Control: no-cache" \
-d '{
"frames": [
{
"text": "USDCHF",
"icon": "i34",
"index": 0
}
]
}' \
https://developer.myurl.com/api/v1/dev/widget/update/com.myurl.7a9c72294c097a37f0f0a3337f5ad444598f21/1
PS: Line by line work perfectly
Thanks

Curl command with option -d issue

Trying to send some data via API call (curl) but having issue with the format of the curl command:
serviceMsg="$(cat /tmp/response_time)"
perfData=$(/bin/echo "${serviceMsg}" | /bin/sed 's/,//g')
StatusCode=0
curl -k -s -v -u user:password -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/process-check-result?service=ExternalURL!ResponseTime' -d "{ \"exit_status\": $StatusCode, \"plugin_output\": \"${perfData}\", \"performance_data\": [ ${perfData} ]}"
Here is the error I am getting:
* Connection #0 to host localhost left intact
{
"error": 400.0,
"status": "Invalid request body: Error: lexical error: invalid character inside string.\n { \"exit_status\": 0, \"plugin_ou\n (right here) ------^\n\n"
}
what I am missing ?
Don't hand-code JSON: use jq to generate it for you:
perfData=$(sed 's/,//g' /tmp/response_time)
json=$(jq -n --arg sc "$StatusCode" --arg pd "$perfData" \
'{exit_status: $sc, plugin_output: $pd, performance_data: [ $pd ]}')
url='https://localhost:5665/v1/actions/process-check-result?service=ExternalURL!ResponseTime'
curl -ksv -u user:password -H 'Accept: application/json' -X POST -d "$json" "$url"

Curl with multiline of JSON

Consider the curl command below, is it possible to allow newline in JSON (without the minify) and execute directly in bash (Mac/Ubuntu)
curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
-d \
'
{
"field1": "test",
"field2": {
"foo": "bar"
}
}'
When I run the command above, seems error occurred at the second {
How to fix the above command?
Updated: actually I was able to run the command without issue previously, not sure why problem happen recently.
I remembered another way to do this with a "Here Document" as described in the Bash man page and detailed here. The #- means to read the body from STDIN, while << EOF means to pipe the script content until "EOF" as STDIN to curl. This layout may be easier to read than using separate files or the "echo a variable" approach.
curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: application/json; charset=utf-8' \
--data-binary #- << EOF
{
"field1": "test",
"field2": {
"foo": "bar"
}
}
EOF
NOTE: Use the --trace <outfile> curl option to record exactly what goes over the wire. For some reason, this Here Document approach strips newlines. (Update: Newlines were stripped by curl -d option. Corrected!)
Along the lines of Martin's suggestion of putting the JSON in a variable, you could also put the JSON in a separate file, and then supply the filename to -d using curl's # syntax:
curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
-d #myfile.json
The disadvantage is obvious (2 or more files where you used to have one.) But on the plus side, your script could accept a filename or directory argument and you'd never need to edit it, just run it on different JSON files. Whether that's useful depends on what you are trying to accomplish.
For some reason, this Here Document approach strips newlines
#eric-bolinger the reason the Heredoc strips newlines is because you need to tell your Heredoc to preserve newlines by quoting the EOF:
curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
-d #- <<'EOF'
{
"field1": "test",
"field2": {
"foo": "bar"
}
}
EOF
Notice the single-ticks surrounding EOF the first time it's defined, but not the second.
You should use outer double quotes, and the escape all inner quotes like this:
curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
-d \
"
{
\"field1\": \"test\",
\"field2\": {
\"foo\": \"bar\"
}
}"
You could assign your json to a var:
json='
{
"field1": "test",
"field2": {
"foo": "bar"
}
}'
Now you can forward this to curl using stdin:
echo $json | curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
-d #-
I think this can be an answer
curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
--data-raw '
{
"field1": "test",
"field2": {
"foo": "bar"
}
}'

Resources