Size: 1136
Comment: echo -ne -> printf; explain the code a little. add an example loop for the function that is to be called within a loop.
|
Size: 1237
Comment: printf instead of echo -n, and avoid embedding parameter expansion inside printf's format string
|
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 ' ' while true; do printf '\b%s' "${sp:i++%n:1}" done |
Line 14: | Line 15: |
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 20: | Line 21: |
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: {{{ sp='/-\|' printf ' ' while true; do printf '\b%.1s' "$sp" sp=${sp#?}${sp%???} 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: |
Line 26: | Line 38: |
((sc==4)) && sc=0 | ((sc==${#sp})) && sc=0 |
Line 34: | Line 46: |
some_work |
some_work ... |
Line 40: | Line 51: |
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 ' ' while true; do printf '\b%s' "${sp:i++%n: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.
If you want it to slow down, put a sleep command inside the loop (after the printf).
A POSIX equivalent would be:
sp='/-\|' printf ' ' while true; do printf '\b%.1s' "$sp" sp=${sp#?}${sp%???} 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 } endspin() { printf "\r%s\n" "$@" } until work_done; do spin some_work ... done endspin
A similar technique can be used to build progress bars.