関数
Bash
ESC=$(printf '\033')
ERASE_LINE="${ESC}[2K"
NEXT_LINE="${ESC}[1E"
PREVIOUS_LINE="${ESC}[1F"
function spinner() {
local i=0
local spin='⠧⠏⠛⠹⠼⠶'
local n=${#spin}
while true; do
sleep 0.1
printf "%s%s" "${NEXT_LINE}" "${ERASE_LINE}"
printf "%s %s" "${spin:i++%n:1}" "$*"
printf "%s\r" "${PREVIOUS_LINE}"
done
}
説明
-
n=${#spin}
:spin
という変数の文字列の長さを取得しています -
printf
: ここではecho -en
と同等。エスケープシーケンスを解釈して最後に改行はしない -
${<文字列>:n:m}
: 文字列のn文字目からm文字分の長さの部分文字列 (※ Bash依存) -
i++%n
: iの数値をnで割ったあまりを返してiに1を加えます -
$*
: spinner関数に渡された引数を全て出力します -
\r
: キャリッジリターン。カーソル位置を行頭に戻します
zsh
ESC=$(printf '\033')
ERASE_LINE="${ESC}[2K"
NEXT_LINE="${ESC}[1E"
PREVIOUS_LINE="${ESC}[1F"
function spinner() {
local idx
local spin='⠧⠏⠛⠹⠼⠶'
local n=${#spin}
while true; do
sleep 0.1
printf "%s%s" "$NEXT_LINE" "$ERASE_LINE"
printf "%s %s" "${spin[idx++ % n + 1]}" "$*"
printf "%s\r" "$PREVIOUS_LINE"
done
}
使用例
spinner proccessing... & pid=$!
sleep 5
kill $pid
wait $pid 2>/dev/null
printf "%s%s%s\n" "$NEXT_LINE" "$ERASE_LINE" 'Done!!'