Differences between revisions 12 and 13
Revision 12 as of 2017-03-31 05:22:26
Size: 1318
Editor: r180-216-10-159
Comment: Empty line removed for aesthetic uniformity.
Revision 13 as of 2017-03-31 05:46:23
Size: 1318
Editor: r180-216-10-159
Comment:
Deletions are marked like this. Additions are marked like this.
Line 47: Line 47:
    printf "\r%s\n" "$@"     printf '\r%s\n' "$@"

Can I do a spinner in Bash?

Sure!

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

Each time the loop iterates, it displays the next character in the sp string, wrapping around as it reaches the end. (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.

To slow it down, the sleep command is included inside the loop (after the printf).

A POSIX equivalent would be:

sp='/-\|'
printf ' '
sleep 0.1
while true; do
    printf '\b%.1s' "$sp"
    sp=${sp#?}${sp%???}
    sleep 0.1
done

If you already have a loop which does a lot of work, you can call the following function at the beginning of each iteration to update the spinner:

sp='/-\|'
sc=0
spin() {
    printf "\b${sp:sc++:1}"
    ((sc==${#sp})) && sc=0
    sleep 0.1
}
endspin() {
    printf '\r%s\n' "$@"
    sleep 0.1
}
until work_done; do
   spin
   some_work ...
done
endspin

A similar technique can be used to build progress bars.


CategoryShell

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