untilループとは

untilは、条件式が真になるまでループを繰り返すシェルスクリプトの構文である。
whileとは逆に、条件式の終了ステータスが非ゼロ(偽)の間はループを継続し、ゼロ(真)になった時点でループを終了する。

until 条件式; do
  コマンド
done

基本的な使い方

例えば、指定したファイルが作成されるまで待機する場合は以下のように書ける。

until [ -f /tmp/ready ]; do
  echo "waiting for /tmp/ready..."
  sleep 1
done
echo "ready!"

[ -f /tmp/ready ]は、ファイルが存在しない間は非ゼロを返すため、ファイルが作成されるまでループが続く。

whileとの違い

同じ処理をwhileで書くと、条件式を否定する必要がある。

while [ ! -f /tmp/ready ]; do
  echo "waiting for /tmp/ready..."
  sleep 1
done
echo "ready!"

untilを使うと否定演算子!を書かずに済み、「〜になるまで待つ」という意図がそのままコードに表れる。
「条件が真になるまで繰り返す」処理を書く場合はuntil、「条件が真の間繰り返す」処理を書く場合はwhileを使うと読みやすくなる。

コマンドの終了ステータスで判定する

until[ ]によるファイルチェックだけでなく、任意のコマンドの終了ステータスで判定できる。
以下は、サーバーが起動してヘルスチェックに成功するまで待つ例である。

until curl -sf http://localhost:8080/health > /dev/null; do
  echo "waiting for server..."
  sleep 2
done
echo "server is up"

curl -sfはHTTPステータスがエラーの場合に非ゼロを返すため、サーバーが正常に応答するまでループが続く。

タイムアウトを設ける

untilは条件を満たすまで無限にループするため、条件が永久に満たされない場合はループが終了しない。
リトライ回数の上限を設けてタイムアウトさせる場合は、カウンタを併用する。

count=0
until curl -sf http://localhost:8080/health > /dev/null; do
  count=$((count + 1))
  if [ "$count" -ge 30 ]; then
    echo "timeout waiting for server" >&2
    exit 1
  fi
  sleep 2
done
echo "server is up"

参考リンク

» GNU Bash Manual: Looping Constructs