Display Spinner while waiting for some process to finish
Have your while
loop watch for your real command to exit. I'll assume a Linux environment that has /proc entries for each PID, but you could slice it other ways:
#!/bin/bash
# your real command here, instead of sleep
sleep 7 &
PID=$!
i=1
sp="/-\|"
echo -n ' '
while [ -d /proc/$PID ]
do
printf "\b${sp:i++%${#sp}:1}"
done
This shell script should do what you're looking for:
#!/usr/bin/env bash
show_spinner()
{
local -r pid="${1}"
local -r delay='0.75'
local spinstr='\|/-'
local temp
while ps a | awk '{print $1}' | grep -q "${pid}"; do
temp="${spinstr#?}"
printf " [%c] " "${spinstr}"
spinstr=${temp}${spinstr%"${temp}"}
sleep "${delay}"
printf "\b\b\b\b\b\b"
done
printf " \b\b\b\b"
}
("$@") &
show_spinner "$!"
Assuming you store the shell script in a file named spinner
, you can invoke it like this to display a spinner while the command sleep 10
is running:
$ spinner sleep 10
Here's another fancy spinner which you can use like this:
spinner ping google.com
echo "ping exited with exit code $?"
spinner sleep 10
echo "sleep exited with exit code $?"
It has 12 themes and picks one randomly.
#!/bin/bash
# Shows a spinner while another command is running. Randomly picks one of 12 spinner styles.
# @args command to run (with any parameters) while showing a spinner.
# E.g. ‹spinner sleep 10›
function shutdown() {
tput cnorm # reset cursor
}
trap shutdown EXIT
function cursorBack() {
echo -en "\033[$1D"
}
function spinner() {
# make sure we use non-unicode character type locale
# (that way it works for any locale as long as the font supports the characters)
local LC_CTYPE=C
local pid=$1 # Process Id of the previous running command
case $(($RANDOM % 12)) in
0)
local spin='⠁⠂⠄⡀⢀⠠⠐⠈'
local charwidth=3
;;
1)
local spin='-\|/'
local charwidth=1
;;
2)
local spin="▁▂▃▄▅▆▇█▇▆▅▄▃▂▁"
local charwidth=3
;;
3)
local spin="▉▊▋▌▍▎▏▎▍▌▋▊▉"
local charwidth=3
;;
4)
local spin='←↖↑↗→↘↓↙'
local charwidth=3
;;
5)
local spin='▖▘▝▗'
local charwidth=3
;;
6)
local spin='┤┘┴└├┌┬┐'
local charwidth=3
;;
7)
local spin='◢◣◤◥'
local charwidth=3
;;
8)
local spin='◰◳◲◱'
local charwidth=3
;;
9)
local spin='◴◷◶◵'
local charwidth=3
;;
10)
local spin='◐◓◑◒'
local charwidth=3
;;
11)
local spin='⣾⣽⣻⢿⡿⣟⣯⣷'
local charwidth=3
;;
esac
local i=0
tput civis # cursor invisible
while kill -0 $pid 2>/dev/null; do
local i=$(((i + $charwidth) % ${#spin}))
printf "%s" "${spin:$i:$charwidth}"
cursorBack 1
sleep .1
done
tput cnorm
wait $pid # capture exit code
return $?
}
("$@") &
spinner $!