views:

275

answers:

3

I want to implement a progress bar showing elapsed seconds in bash. For this, i need to erase the last line shown on the screen ( command "clear" erases all the screen, i need to erase only the line of the progress bar and replace it with the new informations ).

Final result should look like :

"Elapsed time 5 seconds"
Then after 10 seconds i want to replace this sentence ( in the same position in the screen ) by: "Elapsed time 15 seconds"

Any clues to realize this,

Thanks.

Debugger

+4  A: 

echo a carriage return with \r

seq 1 1000000 | while read i; do echo -en "\r$i"; done

from man echo:

-n     do not output the trailing newline
-e     enable interpretation of backslash escapes

\r     carriage return
Ken
`for i in {1..100000}; do echo -en "\r$i"; done` to avoid the seq call :-)
Douglas Leeder
This does exactly what what i need, thanks !!And the use of seq command indeed freezes the termianl :-)
When you use things like "for i in $(...)" or "for i in {1..N}" you are generating all elements before iterating, that's very inefficient for large inputs. You can either take advantage of pipes: "seq 1 100000 | while read i; do ..." or use the bash c-style for loop: "for ((i=0;;i++)); do ..."
tokland
Thanks Douglas and tokland - athough the sequence production wasn't directly part of the question I've changed to tokland's more efficient pipe
Ken
A: 

Use the carriage return character:

echo -e "Foo\rBar" # Will print "Bar"
Mikael S
A: 

The simplest way is to use the \r character I guess.

The drawback is that you can't have complete lines, as it only clears the current line.

Simple example:

time=5
echo -n "Elapsed $time seconds"
sleep 10
time=15
echo -n "Elapsed $time seconds"

echo "\nDone"
Romuald Brunet