13

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 :)

Noob Coder
  • 38
  • 4
nacho4d
  • 43,720
  • 45
  • 157
  • 240

3 Answers3

17

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
choroba
  • 231,213
  • 25
  • 204
  • 289
  • Great answer, @choroba. This makes it complete: `for i in {1..10} ; do echo -n "0[ "; for ((j=0; j' ; for ((j=i;j<=10;j++)) ; do echo -n ' '; done; echo -n $'] 100% \r'; sleep 1; done` – fedorqui Aug 02 '13 at 13:03
12

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
fedorqui
  • 275,237
  • 103
  • 548
  • 598
10

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

user1146332
  • 2,630
  • 1
  • 15
  • 19