Differences between revisions 1 and 2
Revision 1 as of 2007-05-02 23:23:02
Size: 725
Editor: redondos
Comment:
Revision 2 as of 2008-05-09 11:14:31
Size: 1136
Editor: Lhunath
Comment: echo -ne -> printf; explain the code a little. add an example loop for the function that is to be called within a loop.
Deletions are marked like this. Additions are marked like this.
Line 10: Line 10:
        echo -en "\b${sp:i++%${#sp}:1}"         printf "\b${sp:i++%${#sp}:1}"
Line 14: Line 14:
You can also use \r instead of \b. You can use pretty much any character sequence you want as well. If you want it to slow down, put a {{{sleep}}} command inside the loop. The theory here is that each time the loop iterates, it displays the next character in the `sp` string, wrapping around as it reaches the end (where `i` is the position of the current character to display and `${#sp}` is the length of the `sp` string).
Line 16: Line 16:
To use as a function called from a loop on every iteration, for example: The `\b` string is replaced by a 'backspace' character. Alternatively, you could play with `\r` to go back to the beginning of the line.

If you want it to slow down, put a {{{sleep}}} command inside the loop (after the printf).

If you already have a loop which does a lot of work, you can call the following function at the beginning of each iteration in that loop to update the spinner every time an iteration of your loop begins:
Line 21: Line 25:
   echo -ne "\b${sp:sc++:1}"    printf "\b${sp:sc++:1}"
Line 24: Line 28:
endspin() {
   printf "\r%s\n" "$@"
}

until work_done; do
   spin

   some_work
done
endspin
Line 25: Line 39:
When printing the next output line (ie when the spin is over) use: {{{ echo -e "\r$line" }}} or: {{{ echo -en '\r'; echo "$line" }}}

Anchor(faq34)

Can I do a spinner in Bash?

Sure.

    i=1
    sp="/-\|"
    echo -n ' '
    while true
    do
        printf "\b${sp:i++%${#sp}:1}"
    done

The theory here is that each time the loop iterates, it displays the next character in the sp string, wrapping around as it reaches the end (where i is the position of the current character to display and ${#sp} is the length of the sp string).

The \b string is replaced by a 'backspace' character. Alternatively, you could play with \r to go back to the beginning of the line.

If you want it to slow down, put a sleep command inside the loop (after the printf).

If you already have a loop which does a lot of work, you can call the following function at the beginning of each iteration in that loop to update the spinner every time an iteration of your loop begins:

sp="/-\|"
sc=0
spin() {
   printf "\b${sp:sc++:1}"
   ((sc==4)) && sc=0
}
endspin() {
   printf "\r%s\n" "$@"
}

until work_done; do
   spin

   some_work
done
endspin

A similar technique can be used to build progress bars.

BashFAQ/034 (last edited 2023-10-26 18:03:57 by emanuele6)