ぼくの薄い本

技術的なメモを残していく薄い本的なものです

bash でダウンロード中に Spinner を回す

スクリプトで時間がかかる処理をしているときにかっこいい表示をさせたいですよね?

僕はしたいです。

f:id:takuyachallenge:20171009164922g:plain

こんなやつです。

早速コード

#!/bin/bash
curl -L https://archive.mozilla.org/pub/opus/opus-1.2.1.tar.gz 2>/dev/null &
pid=$!

spin[0]="-"
spin[1]="\\"
spin[2]="|"
spin[3]="/"

echo -n "[Fetching] ${spin[0]}"
while kill -0 $pid 2>/dev/null
do
  for i in "${spin[@]}"
  do
    echo -ne "\b$i"
    sleep 0.1
  done
done
echo -ne "\bDone\n"

解説

簡単に解説します。

まず動かしたいコマンドを記述し、標準出力に出ないように /dev/null にリダイレクトして、バックグラウンドで動かします。そして、そのプロセスIDを pid に格納します。

curl -L https://archive.mozilla.org/pub/opus/opus-1.2.1.tar.gz 2>/dev/null &
pid=$!

グルグルさせたい文字を配列で作ります。

spin[0]="-"
spin[1]="\\"
spin[2]="|"
spin[3]="/"

こでは [Fetching] の文字の後で pid が終わるまでグルグルするようにしています。 キモは \b で一文字削除してから次の文字を書いていることです。 こうすることで、文字がグルグルしているように見えます。 最後に Done を表示させて改行して終わりです。

echo -n "[Fetching] ${spin[0]}"
while kill -0 $pid 2>/dev/null
do
  for i in "${spin[@]}"
  do
    echo -ne "\b$i"
    sleep 0.1
  done
done
echo -ne "\bDone\n"

おわりに

エラー処理をちゃんとするとか、関数化して汎用性を高めるとかもっと工夫はできますが、最低限こうすればいいという処理を書きました。

ただ機能を実装するだけではなくて、見た目にもこだわっていきたいですね。