I have some sort of stopwatch script that looks like:
BEGIN=$(date +%s)
while true; do
NOW=$(date +%s)
DIFF=$(($NOW - $BEGIN))
MINS=$(($DIFF / 60))
SECS=$(($DIFF % 60))
HOURS=$(($DIFF / 3600))
# \r is a "carriage return" - returns cursor to start of line
printf "\rDownload time: %02d:%02d:%02d" $HOURS $MINS $SECS
sleep 1
done
So while
some condition is true, it will keep adding 1 second per loop. I want this condition to be something along the lines:
function download()
{
HOMEPAGE_RESPONSE=$(curl -w "\n%{http_code}" "https://example.com/")
STATUS_CODE=$(echo "$HOMEPAGE_RESPONSE" | sed -n '$p')
HTML=$(echo "$HOMEPAGE_RESPONSE" | sed '$d')
}
download
# Whenever the STATUS_CODE is 200, exit the stopwatch script
# Can be any other condition that stops the loop when cURL has finished
while (( $STATUS_CODE != 200 )); do
NOW=$(date +%s)
DIFF=$(($NOW - $BEGIN))
MINS=$(($DIFF / 60))
SECS=$(($DIFF % 60))
HOURS=$(($DIFF / 3600))
# \r is a "carriage return" - returns cursor to start of line
printf "\rDownload time: %02d:%02d:%02d" $HOURS $MINS $SECS
sleep 1
done
The idea is to initiate the cURL download and at the same time the download starts, execute the stopwatch script. This will eventually start counting seconds and printing the stopwatch until
the download is complete. I am also aware of the until
command which I found in this post. Example:
until $(curl --output /dev/null --silent --head --fail http://myhost:myport); do
printf '.'
sleep 5
done
I don't know how to apply until
since my cURL is stored in a variable within the function called download()
and I want to be able to use the STATUS_CODE
and the HTML
content separately.
Can anyone tell me how I can do so?
UPDATE
Given @Inian 's answer this is what I have so far:
function download()
{
homepage_response=$(curl -s -w "\n%{http_code}" "https://example.com/")
status_code=$(echo "$homepage_response" | sed -n '$p')
html=$(echo "$homepage_response" | sed '$d')
printf '%s' "${status_code}"
}
# Calling the function $(download)
until [[ "$(download)" == "200" ]]; do
printf '.\n'
sleep 1
done
echo $status_code
According to my understanding, this should execute the function download()
and print .
each on a different line until
cURL returns the status_code
of 200
.
This, however, initiates cURL but neither it prints .
nor does it echo the status_code
which should be equivalent to 200
.
I cannot guess why.
ALTERED ANSWER
According to @chepner 's answer I came up with:
download()
{
homepage_response=$(curl -s -w "\n%{http_code}" "https://example.com/")
status_code=$(echo "$homepage_response" | sed -n '$p')
html=$(echo "$homepage_response" | sed '$d')
# printf '%s' "${status_code}"
}
start_stopwatch () {
BEGIN=$(date +%s)
while true; do
NOW=$(date +%s)
DIFF=$(($NOW - $BEGIN))
MINS=$(($DIFF / 60))
SECS=$(($DIFF % 60))
HOURS=$(($DIFF / 3600))
printf "\rDownload time: %02d:%02d:%02d" "$HOURS" "$MINS" "$SECS"
sleep 1 & wait # Make it interruptible
done
}
start_stopwatch & sw_pid=$!
# # For testing purposes
# echo "$sw_pid"
# Kill background stopwatch if script EXITS beforehand
set -e
kill_sw() {
kill "$sw_pid"
}
trap kill_sw EXIT
# Call function download()
download
printf "\n"
kill "$sw_pid"
Out of precaution I added set -e
which calls the function kill_sw()
whenever the script gets interrupted before kill "$sw_pid"
is even executed at the end.