Sometimes I see some commands in the terminal that print results to stdout but in the same line. For example wget prints an arrow like below:
0[=> ]100%
0[ => ]100%
0[ => ]100%
0[ => ]100%
0[ =>]100%
but it is printed out to the same line so it looks like the arrow is moving. How can I achieve the same thing in my programs using bash or sh? Do I need to use other tools?
UPDATE:
I know I mentioned wget, which comes by default in linux, GNU based unices ... Is there a general approach that works on BSDs too? (like OSX) -> OK, If I use bash instead of sh then it works :)
You can also use ANSI/VT100 terminal escape sequences
to achieve this.
Here is a short example. Of course you can combine the printf
statements to one.
#!/bin/bash
MAX=60
ARR=( $(eval echo {1..${MAX}}) )
for i in ${ARR[*]} ; do
# delete from the current position to the start of the line
printf "\e[2K"
# print '[' and place '=>' at the $i'th column
printf "[\e[%uC=>" ${i}
# place trailing ']' at the ($MAX+1-$i)'th column
printf "\e[%uC]" $((${MAX}+1-${i}))
# print trailing '100%' and move the cursor one row up
printf " 100%% \e[1A\n"
sleep 0.1
done
printf "\n"
With escape sequences you have the most control over your terminal screen.
You can find an overview of possible sequences at [1].
[1] http://ascii-table.com/ansi-escape-sequences-vt-100.php
You can use \r
for this purpose:
For example this will keep updating the current time in the same line:
while true; do echo -ne "$(date)\r"; done
Use the special character \r
. It returns to the beginning of the line without going to the next one.
for i in {1..10} ; do
echo -n '['
for ((j=0; j<i; j++)) ; do echo -n ' '; done
echo -n '=>'
for ((j=i; j<10; j++)) ; do echo -n ' '; done
echo -n "] $i"0% $'\r'
sleep 1
done
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With