Reputation: 1053
I have this simple script:
printf "* Download Status: Pending..."
# Get HTML content from homepage
homepage=$(curl -s "https://example.com/")
wait
printf "\r* Download Status: Successful\n"
The \r
simulates carriage return and prints Download Status: Successful
after the download finishes, hereby removing Download Status: Pending...
. This works flawlessly.
If I omit the -s
flag, curl
will show the statistics until the download is complete.
curl
is finished?I tried using something like:
printf "< Download Status: Pending...\n\n"
# Get HTML content from homepage
homepage=$(curl "https://example.com/")
wait
printf "\r\r\r\r\r\r> Download Status: Successful\n"
The reason for me using that many \r
is because I'm leaving some space at the beginning (\n
) and the curl
statistics themselves are 3 lines long. I thought this might remove them but it obviously doesn't, instead it outputs both of the printf
with the curl
stats in between them!
ALTERED ANSWER
According to @jmd_dk 's genius use of variables, this worked for my case:
# Set ANSI codes as variables
esc="\x1b"
esc_up="${esc}[1A"
esc_erase="${esc}[K"
newline="\n"
# Display status before download
printf "* Download Status: Pending...${newline}${newline}"
# Initiante cURL & wait for HTML content from the homepage
homepage=$(curl "https://example.com/")
wait
# Delete all lines up to download status
printf "${esc_up}${esc_erase}"
printf "${esc_up}${esc_erase}"
printf "${esc_up}${esc_erase}"
printf "${esc_up}${esc_erase}"
printf "${esc_up}${esc_erase}"
# Display status after completion
echo "* Download Status: Successful"
I delete all lines else some parts of the curl
stats will be showed, making the output messy.
Upvotes: 1
Views: 795
Reputation: 27225
\r
does not delete it line, it moves the cursor to the beginning of the current line.
Example: echo Test; printf '\r_'
will print _est
.
To delete the current line using \r
, you would have to use
printf '\r '
Note the spaces that will (hopefully) overwrite everything in the current line.
\r
always stays in the same line. Multiple subsequent \r
s will have the same effect as just one. To delete other lines you have to use other escape sequences, such as
\033[<N>A
move the cursor up <N>
lines.\033[K
erase to end of line (just like \r
with lots of spaces).curl
shows its progress in three lines. On top of them, there is your Download Status: Pending..."
message. To erase them all
\r\033[4A
go to the left and four rows up\033[K\n
delete the 1st line and go to the 2nd\033[K\n
delete the 2nd line and go to the 3rd\033[K\n
delete the 3rd line and go to the 4th\033[K
delete the 4th line\r\033[4A
go to the left and four rows up againDownload Status: Successful
print the new messageThis leaves us with the command
echo "* Download Status: Pending..."
homepage=$(curl "https://example.com/")
wait
printf '\r\033[4A\033[K\n\033[K\n\033[K\n\033[K' # delete 4 lines
printf '\r\033[4A' # reposition cursor
echo '* Download Status: Successful'
You can write the last three lines as one printf
, but that would be even harder to read.
If you don't mind loosing all the output (even the output from commands executed before your script), you can clear the complete screen with just one escape sequence: \033c
.
echo "* Download Status: Pending..."
homepage=$(curl "https://example.com/")
wait
printf '\033c' # clear screen
echo '* Download Status: Successful'
Upvotes: 3
Reputation: 13100
One solution would be to make use of more complex (ANSI) escape sequences. Example (save this to a script before running):
esc="\x1b"
esc_up="${esc}[1A"
esc_erase="${esc}[K"
echo Line 1
echo Line 2
echo Line 3
sleep 3
printf "${esc_up}${esc_up}" # Move cursor two up
printf "${esc_erase}" # Delete current line
echo New
This will print the three lines, then move up two lines and overwrite the text. To understand esc_erase
, try leaving this line out.
The world of ANSI escape sequences is vast an daunting. The above example should suffice for your immediate needs. Much more information is of course available.
Upvotes: 2