インスタンスの起動スクリプトとかを書いてるときによく欲しいと思うやつです。
例えば、 service nginx start
が実行されたあとに curl -i localhost | grep "200 OK"
とかをすると、サービスがそれなりに動いていることが確認できてよかったりするのですが、あまりにも直後だとサーバの起動が間に合わず、curl が失敗してしまいます。nginxだとまだましだけど、アプリケーションサーバだとそれなりに時間がかかったりする。
古典的な解決方法は、 sleep 30
です。簡単だけど、アプリケーションが巨大になってくると30秒では起動しないこともある。じゃぁ sleep 60
が妥当か?でも、サーバインスタンスの起動スクリプト全体はできるだけ早く立ち上がってほしい。困った。
なので、curlが成功するまで叩き続ける、みたいなスクリプトに仕上げたくなるわけです。
書いたらそんなに苦労しなかった。
service nginx start
until curl -i localhost | grep "200 OK"
do
sleep 5
done
こんなかんじ。makefileの中で使ったりするために1行で書くと、
until (curl -i localhost | grep "200 OK") do sleep 5; done
リトライの頻度を増やしたいときは、 sleep 1
とかにしましょう。それ以下は usleep 500
とか、もしくは sleep 0.1
とかも結構できるようです(要確認)。
ずっと実行され続けてつらい?timeoutと組み合わせてみましょう。untilなどと組み合わせるのが辛かったので、shコマンド経由で:
timeout 60 sh -c 'until (curl -i localhost | grep "200 OK") do sleep 1; done'
簡単。untilの条件が複雑になるとクオートのエスケープとかが辛くなるので、そのときは別スクリプトに分割していきましょう。
いままでは bash retry until とかでググってたのであんまり良い答えにたどり着かなかったけど、これでええんやっていうことを昨日気づいたので、そのメモでした。
インターバルを増やしていく場合:
i=1; until (curl -i localhost | grep "200 OK") do sleep $i; i=$(($i*2)); done
難しくはない。