使用例
spinner proccessing... & pid=$!
sleep 5
kill $pid
wait $pid 2>/dev/null
printf "%s%s\n" "$ERASE_LINE" 'Done!!'
aws ec2 start-instances \
--profile "$AWS_PROFILE" \
--instance-ids "$EC2_INSTANCE_ID" \
--output text >/dev/null
spinner 'インスタンスの起動を待機中...' &
spinner_pid=$!
aws ec2 wait instance-running \
--profile "$AWS_PROFILE" \
--instance-ids "$EC2_INSTANCE_ID"
stop_spinner "$spinner_pid" "${GREEN}✓${RESET} インスタンスが起動しました"
spinner 'ステータスチェックの完了を待機中...' &
spinner_pid=$!
aws ec2 wait instance-status-ok \
--profile "$AWS_PROFILE" \
--instance-ids "$EC2_INSTANCE_ID"
stop_spinner "$spinner_pid" "${GREEN}✓${RESET} ステータスチェックが完了しました"
関数
Bash
ESC=$(printf '\033')
CSI="${ESC}["
RESET="${CSI}0m"
GREEN="${CSI}32m"
ERASE_LINE="${CSI}2K"
HIDE_CURSOR="${CSI}?25l"
SHOW_CURSOR="${CSI}?25h"
# スピナー表示
spinner() {
local i=0
local spin='⠧⠏⠛⠹⠼⠶'
local n=${#spin}
while true; do
sleep 0.1
printf '%s' "${ERASE_LINE}"
printf '%s %s' "${GREEN}${spin:i++%n:1}${RESET}" "$*"
printf '%s\r' "${HIDE_CURSOR}"
done
}
# スピナー停止
stop_spinner() {
local pid=$1
local message=$2
kill "$pid" 2>/dev/null || true
wait "$pid" 2>/dev/null || true
printf '%s%s\n' "${ERASE_LINE}" "$message"
printf '%s' "${SHOW_CURSOR}"
}
説明
-
n=${#spin}:spinという変数の文字列の長さを取得しています -
printf: ここではecho -enと同等。エスケープシーケンスを解釈して最後に改行はしない -
${<文字列>:n:m}: 文字列のn文字目からm文字分の長さの部分文字列 (※ Bash依存) -
i++%n: iの数値をnで割ったあまりを返してiに1を加えます -
$*: spinner関数に渡された引数を全て出力します -
\r: キャリッジリターン。カーソル位置を行頭に戻します - 最初のCSIについては参考記事を参照されたい12
zsh
ESC=$(printf '\033')
CSI="${ESC}["
RESET="${CSI}0m"
GREEN="${CSI}32m"
ERASE_LINE="${CSI}2K"
HIDE_CURSOR="${CSI}?25l"
function spinner() {
local idx
local spin='⠧⠏⠛⠹⠼⠶'
local n=${#spin}
while true; do
sleep 0.1
printf "%s" "$ERASE_LINE"
printf "%s %s" "${GREEN}${spin[idx++ % n + 1]}${RESET}" "$*"
printf "%s\r" "$HIDE_CURSOR"
done
}
参考
- command line - How to create a rotation animation using shell script? - Ask Ubuntu
- BashFAQ/034 - Greg's Wiki

