curl+ロードスピナーでURLへアクセスできるか確認する
WEB開発を行っている場合、JavaであればJbossの再起動、PHPであればApacheの再起動を行う場面が多くあります。
大きいシステムであればあるほど、サーバー再起動が長くなり、いつサーバーが立ち上がったのかすぐに知りたいものですよね?
そこで、curlコマンドによりサーバーが立ち上がったのかどうかを判定するシェルを作ってみました。
さらに、見栄えを良くするためにロードスピナーも加えて、オシャレにサーバー再起動を感知してみましょう!
curlとロードスピナーでサーバー再起動を感知
curlコマンドを使用することで、404などのエラーを簡単に感知することができます。
シェルへ対象URLとなる引数を渡し、エラーが出なくなるまでcurlコマンドを繰り返すというものになります。
繰り返す間は、ロードスピナにて進捗を目視し、コマンドが動作していることを監視することができます。
以下がエラーとロードスピナーを実装したデモンストレーションとなります。
本サイトは、9999ポートを割り当てていないため、curlによる結果はエラーが期待されます。
対して、WEBサイトがエラーではない場合は、「SUCCESS」を表示させております。
ソースコード全体
curl+ロードスピナーでWEBサイトの起動を感知するシェルスクリプトは以下の通りとなります。
#!/usr/bin/env zsh
if [ $# -ne 1 ]; then
echo "引数となるURLを指定してください。" 1>&2
exit 1
fi
v='..'
spas=' '
c=0
# header だけ取得
until $(curl -o /dev/null -s -H -f $1 -k); do
# 最大5分待つ
((c++)) && ((c==60)) && break_flag=true && break
#sleep 5s
str=$spas$str
echo -en $v'\b' 1>&2;
for i in `seq 1 1 5`
do
echo -en '|\b' 1>&2; sleep 0.05;
echo -en '/\b' 1>&2; sleep 0.05;
echo -en '-\b' 1>&2; sleep 0.05;
echo -en '\\\b' 1>&2; sleep 0.05;
done
done
# 最後の出力を消す
echo -en ' \b' 1>&2;
# .を消す
for ((i=0;i<$c;i++)) do echo -en '\b \b' 1>&2;
done
if [ "$break_flag" = true ] ; then
echo "TimeOut"
else
echo "SUCCESS"
fi
exit 0
シェルスクリプトへ指定のURLを渡すために、以下のように引数を判定しております。
if [ $# -ne 1 ]; then
echo "引数となるURLを指定してください。" 1>&2
exit 1
fi
1行目にて、引数の数が1ではない場合の判定を行っております。
引数が無い場合は、echoにより「引数となるURLを指定してください」と表示し、「exit 1」でシェルスクリプトを終了させております。
次が、本シェルスクリプトのメイン機能部分となります。
until $(curl -o /dev/null -s -H -f $1 -k); do
# 最大5分待つ
((c++)) && ((c==60)) && break_flag=true && break
#sleep 5s
str=$spas$str
echo -en $v'\b' 1>&2;
for i in `seq 1 1 5`
do
echo -en '|\b' 1>&2; sleep 0.05;
echo -en '/\b' 1>&2; sleep 0.05;
echo -en '-\b' 1>&2; sleep 0.05;
echo -en '\\\b' 1>&2; sleep 0.05;
done
done
curlにて指定しているオプションは以下の通りとなります。
オプション | 処理内容 |
---|---|
-o | ファイル名を指定したダウンロード |
-s | エラーを表示させる |
-H | ヘッダー情報の付与 |
-f | 失敗した場合は出力しない |
-k | 証明書なしのSSLサイトを許可 |
これらのオプションの詳しい内容は、curlのヘルプをご参照ください。
curl -h
curlには、シェルスクリプトの引数であるURLを「$1」にて取得しております。
ループ処理内では、curlにて「-f」を指定しているので何も出力されていない間は、ループが回り続けます。
変数「c」にて、カウントを行い、「c」が60(5分)に達したら、「break_flag」へtrueを代入し、breakにてタイムアウトを行っています。
((c++)) && ((c==60)) && break_flag=true && break
ループの回数を把握するために1ループごとに「.」の表示を行っております。
echo -en $v'\b' 1>&2;
ロードスピナーを行っている箇所はこちらとなります。
for i in `seq 1 1 5`
do
echo -en '|\b' 1>&2; sleep 0.05;
echo -en '/\b' 1>&2; sleep 0.05;
echo -en '-\b' 1>&2; sleep 0.05;
echo -en '\\\b' 1>&2; sleep 0.05;
done
「for」文にて「seq」を実施しておりますが、以下のようなオプションとなっており、今回は5秒指定しています。
seq [初期値] [間隔] [最終値]
続いてechoコマンドのオプションの意味はこちらとなります。
オプション | 処理内容 |
---|---|
-e | 改行を表示 |
-n | 出力文字の最後の改行をしない |
補足として、「\b」という書き方はバックスペースを意味しており、表示させた後にすぐに文字を削除することで、擬似的に回転(スピナー)を行っております。
これを「sleep」により時間を開けながら次の文字を表示させては削除を5秒間のループで行っております。
好みが分かれますが、curlの実行回数ごとに表示させていた「.」を同じく「\b」により変数「c」数だけ削除を行います。
# 最後の出力を消す
echo -en ' \b' 1>&2;
# .を消す
for ((i=0;i<$c;i++)) do echo -en '\b \b' 1>&2;
done
「.」とスピナーを削除した後は、「break_flag」を元にcurlが成功したのか判定を行います。
if [ "$break_flag" = true ] ; then
echo "TimeOut"
else
echo "SUCCESS"
fi
exit 0
単純に「if」文により「break_flag」がtureであればタイムアウト判定とし、そうでなければ成功と判断しております。
以上で、curl+ロードスピナーを実装することができましたが、同期っぽく見えて非同期となっておりますので、注意が必要です。
また、プロジェクトによっては、ロードスピナーを嫌う場合もありますので、その場合は「.」で対応する必要があります。