Show progress bar in curl without showing response content - bash

Is there are way within Bash to hide the response body of a curl GET request whilst still showing a progress bar?
--progress-bar Shows a minified version of the default bar however still outputs everything.
Likewise with --silent which hides everything which is unhelpful for the volume of requests.
My current code is,
for i in $(cat scripts/urls.txt); do
file="scripts/output.txt"
content=$(curl --location --request GET $i -H 'Authorization: ...')
"$content" >> $file
cat $file
sleep 5
done

The progress bar is sent to stderr. The response is sent to stdout. To redirect and append the response to a file you could use the >> operator:
while read -r i; do
file="scripts/output.txt"
curl --location --request GET $i -H 'Authorization: ...' >> $file
sleep 5
done < scripts/urls.txt

$ curl -X GET http://www.example.com > /dev/null
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1256 100 1256 0 0 22445 0 --:--:-- --:--:-- --:--:-- 22836

Related

Curl websockets

I'm working on one bash script. I need to get data from websocket on my esp32. I need to get value from the sensor. Issue is that sometimes I can't get connection right when i send request.
flow_value_raw=$(timeout 1s \
curl \
--no-buffer \
--header "Connection: Upgrade" \
--header "Upgrade: websocket" \
--header "Host: $ip$port/$flow" \
--header "Origin: http://$ip$port/$flow" \
--header "Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQ==" \
--header "Sec-WebSocket-Version: 13" \
http://$ip:$port/$flow 2>/dev/null)
flow_value_raw=${flow_value_raw:2}
In this way I trigger curl every sec, but lot of time I get nothing from curl. Is there any way I can tell curl to just get one value from respond? If i use just curl without timeout I get multiple response.
i am not entirely sure what you mean or seek.
so i am trying to respond to
any whay i can tell curl to just get one value from respond
a while-loop where the condition is true will continue indefinitely. an infinite loop
the output from curl is saved in flow_value_raw
if [ -n "${flow_value_raw} ] checks if the string variable non-empty
- if non-empty, i.e. values were outputted by curl, break out of infinite loop
- else sleep for 1 second and repeat
while true; do
local flow_value_raw=$(timeout 1 curl ...args)
if [ -n "${flow_value_raw}" ]; then
break
else
sleep 1
fi
done
PS from man timeout
Start COMMAND, and kill it if still running after DURATION.

Query a REST API with Bearer token via UNIX bash script

I managed to receive a token which looks reasonable and it is saved to the token variable.
I'm using this curl command to query the API:
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header "Authorization: Bearer $token" -d '*JSON format query*' '*Link*' | jq -r
In the API documentation provided by Swagger UI, inputting the JSON format query gives a Response Code 200 with a sensible Response Body. Basically the above code is just copied from the curl command generated by Swagger UI.
But I don't receive any output from my bash script besides:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 655 0 0 100 655 0 3266 --:--:-- --:--:-- --:--:-- 3275
[0][user#ip-xyz:/home/user/abc]
I tried playing around with the script (e.g. replacing $token with something unsensible) and still get the same output which makes me question if the token is even required and/or correct.

Escaping multiple layers of mixed quotes for a curl command executed inside a bash script

I have the following bash script that uses its arguments to hit a RESTful web service (via curl) and prints out both the curl request made as well as the response:
#! /bin/bash
# arguments:
# $1 - username
# $2 - password
#
# outputs:
# if the script exits with a non-zero status then something went wrong
# verify that we have all 6 required arguments and fail otherwise
if [ "$#" -ne 2 ]; then
echo "Required arguments not provided"
exit 1
fi
# set the script arguments to meaningful variable names
username=$1
password=$2
# login and fetch a valid auth token
req='curl -k -i -H "Content-Type: application/json" -X POST -d ''{"username":"$username","password":"$password"}'' https://somerepo.example.com/flimflam'
resp=$(curl -k -i -H "Content-Type: application/json" -X POST -d ''{"username":"$username","password":"$password"}'' https://somerepo.example.com/flimflam)
# echo the request for troubleshooting
echo "req = $req"
if [ -z "$resp" ]; then
echo "Login failed; unable to parse response"
exit 1
fi
echo "resp = $resp"
When I run this I get:
$ sh myscript.sh myUser 12345#45678
curl: (3) Port number ended with '"'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0curl: (6) Could not resolve host: 12345#45678"
100 1107 100 1093 100 14 2849 36 --:--:-- --:--:-- --:--:-- 2849
req = curl -k -i -H "Content-Type: application/json" -X POST -d {"username":"$username","password":"$password"} https://somerepo.example.com/flimflam
resp = HTTP/1.1 400 Bad Request...(rest omitted for brevity)
Obviously, I'm not escaping the various layers of single- and double-quotes inside the curl statement correctly, as is indicated by outputs like:
curl: (6) Could not resolve host: 12345#45678"
and:
req = curl -k -i -H "Content-Type: application/json" -X POST -d {"username":"$username","password":"$password"} https://somerepo.example.com/flimflam
where the username/password variables are not parsing.
In reality my script takes a lot more than 2 arguments, which is why I'm changing them to have meaningful variable names (such as $username instead of $1) so its more understandable and readable.
Can anyone spot where I'm going awry? Thanks in advance!
Update
I tried the suggestion which turns the req into:
curl -k -i -H 'Content-Type: application/json' -X POST -d "{'username':'myUser','password':'12345#45678'}" https://somerepo.example.com/flimflam
However this is still an illegal curl command and instead needs to be:
curl -k -i -H 'Content-Type: application/json' -X POST -d '{"username":"myUser","password":"12345#45678"}' https://somerepo.example.com/flimflam
First, as I said in a comment, storing commands in variables just doesn't work right. Variables are for data, not executable code. Second, you have two levels of quoting here: quotes that're part of the shell syntax (which are parsed, applied, and removed by the shell before the arguments are passed to `curl), and quotes that're part of the JSON syntax.
But the second problem is actually worse than that, because simply embedding an arbitrary string into some JSON may result in JSON syntax errors if the string contains characters that're part of JSON syntax. Which passwords are likely to do. To get the password (and username for that matter) embedded correctly in your JSON, use a tool that understands JSON syntax, like jq:
userinfo=$(jq -n -c --arg u "$username" --arg p "$password" '{"username":$u,"password":$p}')
Explanation: this uses --arg to set the jq variables u and p to the shell variables $username and $password respectively (and the double-quotes around the shell variables will keep the shell from doing anything silly to the values), and creates a JSON snippet with them embedded. jq will automatically add appropriate quoting/escaping/whatever is needed.
Then, to use it with curl, use something like this:
resp=$(curl -k -i -H "Content-Type: application/json" -X POST -d "$userinfo" https://somerepo.example.com/flimflam)
Again, the double-quotes around $userinfo keep the shell from doing anything silly. You should almost always put double-quotes around variables references in the shell.
Note that I never used the req variable to store the command. If you need to print the command (or its equivalent), use something like this:
printf '%q ' curl -k -i -H "Content-Type: application/json" -X POST -d "$userinfo" https://somerepo.example.com/flimflam
echo
The %q format specifier tells the shell to add appropriate quoting/escaping so that you could run the result as a shell command, and it'd work properly. (And the echo is there because printf doesn't automatically add a newline at the end of its output.)
try changing this:
req='curl -k -i -H "Content-Type: application/json" -X POST -d ''{"username":"$username","password":"$password"}'' https://somerepo.example.com/flimflam'
to this
req="curl -k -i -H 'Content-Type: application/json' -X POST -d \"{'username':'$username','password':'$password'}\" https://somerepo.example.com/flimflam"
and similarly for the resp
ah those pesky "curly" thingies...
how 'bout...
req="curl -k -i -H 'Content-Type: application/json' -X POST -d '{\"username\":\"$username\",\"password\":\"$password\"}' https://somerepo.example.com/flimflam"
This needs even more escaping:
With:
resp=$(curl -k -i -H "Content-Type: application/json" -X POST -d "{\"username\":\"$username\",\"password\":\"$password\"}" https://somerepo.example.com/flimflam)
In bash, the variables are still expanded when they're inside single quotes that are inside double quotes.
And you'll need the \" double quotes in the payload as per the JSON definition.
EDIT: I rerun the curl through a HTTP proxy and corrected the script line (see above, removed the single quotes). Results (in raw HTTP) are now:
POST /flimflam HTTP/1.1
Host: somerepo.example.com
User-Agent: curl/7.68.0
Accept: */*
Content-Type: application/json
Content-Length: 44
Connection: close
{"username":"user","password":"12345#abcde"}
(which should be fine)

cURL POST request with bearer token results in "Could not resolve host: POST"

I'm issuing the following command in zsh to send a POST request with a bearer token.
curl -o -X POST -H "Authorization: Bearer ${TOKEN}" http://localhost:8090/services/item/0
The output I get is the following:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0curl: (6) Could not resolve host: POST
Update 1
I posted a wrong command which I have corrected now. This is what I'm issuing:
curl -X POST -H "Authorization: Bearer ${TOKEN}" http://localhost:8090/services/item/0
I discovered that the behavior is probably related to running the command in a ZSH. When using Bash the call works fine.
The parameter that follows -o is a file name. Your command line begins with:
curl -o -X POST
... which then means that it will save the output to a file named -X. Then the following word (POST) will be treated as a URL since it doesn't start with a dash...
Using that URL (or host name rather) then causes this error:
Could not resolve host: POST
... because curl fails to resolve that host name. It seems there's no host in your network with that name!
I check must work:
curl -H "Authorization: Bearer ${TOKEN}" http://localhost:8090/services/item/0
Or:
curl -H "Authorization: Bearer ${TOKEN}" http://localhost:8090/services/item/0 -o output.txt

system call to curl doesnt shows output from a ruby script

I have a ruby script:
#!/usr/bin/env ruby
`curl -X GET http://host/someurl'
The response doesnt get displayed on terminal when I run this script:
$ ./script.rb
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 146 0 146 0 0 73 0 --:--:-- 0:00:01 --:--:-- 73
$
The server does send some data. If I supply -o to curl:
`curl -X GET -o <some_file> http://host/someurl'
some_file contains server response. Same works for POST requests though:
`curl -X POST --data-binary #some_file http://host/someurl'
This shows the response on terminal. Any idea how I fix this?
just puts it
puts `curl -X GET http://host/someurl`
You have a typo closing your back-tick shell command. You want:
`curl -X GET http://host/someurl`
You used a single quotation mark instead of a trailing back-tick. This causes the expression not to be terminated.

Resources