Differences between revisions 2 and 11 (spanning 9 versions)
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.
Revision 11 as of 2017-03-31 05:19:47
Size: 1320
Editor: r180-216-10-159
Comment: Added `sleep 0.1` after each `printf` to mitigate cpu stress.
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
[[Anchor(faq34)]] <<Anchor(faq34)>>
Line 3: Line 3:
Sure. Sure!
Line 5: Line 6:
    i=1
    sp="/-\|"
    echo -n ' '
    while true
   
do
     printf "\b${sp:i++%${#sp}:1}"
    done
i=0
sp='/-\|'
n=${#sp}
printf
' '
sleep 0.1
while true; do
    printf '\b%s' "${sp:i++%n:1}"
    sleep 0.1
done
Line 14: Line 17:
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). 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 [[BashFAQ/007|length]] of the `sp` string).
Line 18: Line 21:
If you want it to slow down, put a {{{sleep}}} command inside the loop (after the printf). To slow it down, the `sleep` command is included inside the loop (after the `printf`).
Line 20: Line 23:
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: A POSIX equivalent would be:
Line 22: Line 26:
sp="/-\|" 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='/-\|'
Line 25: Line 42:
   printf "\b${sp:sc++:1}"
   ((sc==4)) && sc=0
  printf "\b${sp:sc++:1}"
    ((sc==${#sp})) && sc=0
    sleep 0.1
Line 29: Line 47:
   printf "\r%s\n" "$@"   printf "\r%s\n" "$@"
    sleep 0.1
Line 34: Line 53:

some_work
   some_work ...
Line 40: Line 58:
A similar technique can be used to build progress bars. A similar technique can be used to build [[BashFAQ/044|progress bars]].

----
CategoryShell

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)