[linux] シェルのwhile文の使い方 – 繰り返しコマンド処理する

Linuxのシェルでwhile文は、条件が真である間、指定したコマンドを繰り返し実行するために使用されます。

基本的な構文は以下の通りです:

while [ 条件 ]; do
  コマンド
done

[ 条件 ]の部分で条件を評価し、条件が真であればdo以降のコマンドが実行されます。

条件が偽になるとループが終了します。

例えば、カウンタを使って特定の回数だけループを実行する場合や、ファイルの内容を1行ずつ処理する場合などに利用されます。

この記事でわかること
  • while文の基本構文と使い方
  • 条件式の書き方と注意点
  • 無限ループの作成と制御方法
  • 他の制御構文との組み合わせ
  • 実用的な応用例の紹介

目次から探す

while文の基本構文

while文の基本的な書き方

while文は、指定した条件が真である限り、繰り返し処理を実行するための構文です。

基本的な書き方は以下の通りです。

while [ 条件 ]; do
    # 繰り返し実行するコマンド
done

この構文では、条件が真である限り、dodoneの間に記述されたコマンドが繰り返し実行されます。

条件式の書き方

条件式は、[] で囲まれた部分に記述します。

条件式には、数値の比較や文字列の比較、ファイルの存在確認などが使用できます。

以下は、いくつかの条件式の例です。

スクロールできます
条件式説明
-eq等しい
-ne等しくない
-ltより小さい
-le以下
-gtより大きい
-ge以上
-eファイルが存在するか確認

doとdoneの役割

dodoneは、while文のブロックを定義するために使用されます。

doの後に続くコマンドが、条件が真である限り繰り返し実行され、doneでそのブロックの終了を示します。

これにより、複数のコマンドをまとめて実行することができます。

条件が偽になるまでの動作

while文は、条件が偽になるまで繰り返し処理を行います。

条件が偽になると、ループは終了し、次のコマンドに進みます。

例えば、カウンタを使ったループでは、カウンタが特定の値に達したときに条件が偽となり、ループが終了します。

以下はその例です。

count=1
while [ $count -le 5 ]; do
    echo "カウント: $count"
    count=$((count + 1))
done
カウント: 1
カウント: 2
カウント: 3
カウント: 4
カウント: 5

このように、while文を使うことで、条件に基づいた繰り返し処理を簡単に実装できます。

while文の実用例

カウンタを使ったループ処理

カウンタを使ったループ処理は、特定の回数だけ処理を繰り返す際に便利です。

以下の例では、1から5までの数をカウントアップして表示します。

count=1
while [ $count -le 5 ]; do
    echo "カウント: $count"
    count=$((count + 1))
done
カウント: 1
カウント: 2
カウント: 3
カウント: 4
カウント: 5

ファイルの内容を1行ずつ処理する

while文を使用して、ファイルの内容を1行ずつ読み込むことができます。

以下の例では、sample.txtというファイルの各行を表示します。

while IFS= read -r line; do
    echo "行の内容: $line"
done < sample.txt

このコードを実行すると、sample.txtの各行が次のように表示されます。

行の内容: 1行目のテキスト
行の内容: 2行目のテキスト
行の内容: 3行目のテキスト

ユーザー入力を待つループ

ユーザーからの入力を待つループを作成することも可能です。

以下の例では、ユーザーが exit と入力するまで、入力を受け付け続けます。

input=""
while [ "$input" != "exit" ]; do
    read -p "入力してください (exitで終了): " input
    echo "あなたの入力: $input"
done

このコードを実行すると、ユーザーが入力した内容が表示され、exitと入力するまでループが続きます。

コマンドの実行結果を条件にする

while文は、コマンドの実行結果を条件にしてループを制御することもできます。

以下の例では、pingコマンドを使用して、特定のホストが応答するまで繰り返し確認します。

host="google.com"
while ! ping -c 1 $host &> /dev/null; do
    echo "$host への接続を待っています..."
    sleep 1
done
echo "$host への接続が成功しました!"

このコードを実行すると、指定したホストが応答するまで、接続を待つメッセージが表示され続けます。

接続が成功すると、次のようなメッセージが表示されます。

google.com への接続が成功しました!

このように、while文を使うことで、さまざまな実用的な処理を簡単に実装できます。

無限ループの作成と制御

無限ループの作り方

無限ループは、条件が常に真であるため、終了しないループです。

while文を使って無限ループを作成するには、条件をtrueに設定します。

以下の例では、無限ループを作成しています。

while true; do
    echo "このメッセージは無限に表示されます。"
done

このコードを実行すると、無限に「このメッセージは無限に表示されます。」と表示され続けます。

無限ループを終了するには、通常はCtrl + Cを押します。

無限ループの用途

無限ループは、特定の条件が満たされるまで処理を続ける必要がある場合に便利です。

以下のような用途があります。

スクロールできます
用途説明
サーバーの待機状態クライアントからの接続を待つサーバー
定期的なタスクの実行一定間隔で処理を実行するスクリプト
ユーザー入力の待機ユーザーからの入力を常に受け付ける

breakコマンドでループを抜ける

breakコマンドを使用すると、無限ループを強制的に終了することができます。

以下の例では、ユーザーが exit と入力した場合にループを抜けます。

while true; do
    read -p "入力してください (exitで終了): " input
    if [ "$input" = "exit" ]; then
        echo "ループを終了します。"
        break
    fi
    echo "あなたの入力: $input"
done

このコードを実行すると、ユーザーが exit と入力するまで、入力を受け付け続けます。

continueコマンドで次のループに進む

continueコマンドを使用すると、現在のループの反復をスキップし、次の反復に進むことができます。

以下の例では、偶数の入力をスキップし、奇数の入力のみを表示します。

count=1
while [ $count -le 10 ]; do
    if [ $((count % 2)) -eq 0 ]; then
        count=$((count + 1))
        continue
    fi
    echo "奇数: $count"
    count=$((count + 1))
done

このコードを実行すると、以下のように奇数のみが表示されます。

奇数: 1
奇数: 3
奇数: 5
奇数: 7
奇数: 9

このように、breakcontinueを使うことで、無限ループの制御が柔軟に行えます。

while文と他の制御構文の組み合わせ

if文との組み合わせ

while文とif文を組み合わせることで、条件に応じた処理を柔軟に実行できます。

以下の例では、カウンタが5に達するまでカウントアップし、5に達した場合に特別なメッセージを表示します。

count=1
while [ $count -le 10 ]; do
    if [ $count -eq 5 ]; then
        echo "カウントが5に達しました!"
    else
        echo "カウント: $count"
    fi
    count=$((count + 1))
done
カウント: 1
カウント: 2
カウント: 3
カウント: 4
カウントが5に達しました!
カウント: 6
カウント: 7
カウント: 8
カウント: 9
カウント: 10

for文との違いと使い分け

while文とfor文は、どちらも繰り返し処理を行うための構文ですが、使い分けが重要です。

while文は条件が真である限り繰り返し処理を行い、for文は指定した範囲やリストの要素を順に処理します。

以下は、for文の例です。

for i in {1..5}; do
    echo "カウント: $i"
done

このコードを実行すると、1から5までのカウントが表示されます。

while文は、条件に基づいて無限ループを作成する場合に便利ですが、for文は固定回数のループに適しています。

case文との組み合わせ

while文とcase文を組み合わせることで、複数の条件に基づいた処理を簡潔に記述できます。

以下の例では、ユーザーの入力に応じて異なるメッセージを表示します。

while true; do
    read -p "色を入力してください (red, green, blue, exitで終了): " color
    case $color in
        red)
            echo "赤が選ばれました。"
            ;;
        green)
            echo "緑が選ばれました。"
            ;;
        blue)
            echo "青が選ばれました。"
            ;;
        exit)
            echo "終了します。"
            break
            ;;
        *)
            echo "無効な色です。"
            ;;
    esac
done

このコードを実行すると、ユーザーが色を入力するたびに対応するメッセージが表示されます。

exitと入力するとループが終了します。

until文との違い

until文は、条件が偽である限り繰り返し処理を行います。

while文とは逆の動作をするため、条件が真になるまで処理を続ける場合はwhile文を、条件が偽である間処理を続ける場合はuntil文を使用します。

以下はuntil文の例です。

count=1
until [ $count -gt 5 ]; do
    echo "カウント: $count"
    count=$((count + 1))
done

このコードを実行すると、1から5までのカウントが表示されます。

while文とuntil文は、条件の真偽に応じて使い分けることが重要です。

while文の応用例

複数の条件を使ったループ

while文では、複数の条件を組み合わせてループを制御することができます。

以下の例では、カウンタが1から10の範囲内で、偶数と奇数を区別して表示します。

count=1
while [ $count -le 10 ]; do
    if [ $((count % 2)) -eq 0 ]; then
        echo "$count は偶数です。"
    else
        echo "$count は奇数です。"
    fi
    count=$((count + 1))
done

このコードを実行すると、1から10までの数が偶数か奇数かを表示します。

1 は奇数です。
2 は偶数です。
3 は奇数です。
4 は偶数です。
5 は奇数です。
6 は偶数です。
7 は奇数です。
8 は偶数です。
9 は奇数です。
10 は偶数です。

複数のコマンドを並列実行する

while文を使用して、複数のコマンドを並列に実行することも可能です。

以下の例では、バックグラウンドで2つのコマンドを同時に実行し、両方の処理が完了するまで待機します。

while true; do
    (sleep 3; echo "コマンド1が完了しました。") &
    (sleep 5; echo "コマンド2が完了しました。") &
    wait
    break
done

このコードを実行すると、コマンド1とコマンド2がそれぞれ3秒後と5秒後に完了したことが表示されます。

コマンド1が完了しました。
コマンド2が完了しました。

タイマーやカウントダウンの実装

while文を使って、タイマーやカウントダウンを実装することができます。

以下の例では、10秒のカウントダウンを行います。

count=10
while [ $count -gt 0 ]; do
    echo "$count 秒残っています。"
    sleep 1
    count=$((count - 1))
done
echo "タイマーが終了しました!"

このコードを実行すると、10秒から1秒ずつカウントダウンし、最後にタイマーが終了したことが表示されます。

10 秒残っています。
9 秒残っています。
8 秒残っています。
...
1 秒残っています。
タイマーが終了しました!

特定のプロセスが終了するまで待機する

特定のプロセスが終了するまで待機するために、while文を使用することができます。

以下の例では、sleepコマンドをバックグラウンドで実行し、そのプロセスが終了するまで待機します。

sleep 5 &
pid=$!
while kill -0 $pid 2>/dev/null; do
    echo "プロセスがまだ実行中です..."
    sleep 1
done
echo "プロセスが終了しました!"

このコードを実行すると、5秒間プロセスが実行中であることが表示され、プロセスが終了すると「プロセスが終了しました!」と表示されます。

プロセスがまだ実行中です...
プロセスがまだ実行中です...
プロセスがまだ実行中です...
プロセスがまだ実行中です...
プロセスが終了しました!

このように、while文を使うことで、さまざまな応用例を実装することができます。

よくある質問

while文で無限ループを避けるには?

無限ループを避けるためには、while文の条件を適切に設定することが重要です。

以下のポイントに注意してください。

  • 条件を明確にする: ループが終了する条件を明確に設定し、必ずその条件が満たされるようにします。
  • カウンタやフラグを使用する: ループ内でカウンタやフラグを更新し、条件が偽になるようにします。
  • 適切な終了条件を設ける: ユーザー入力や特定の条件に基づいてループを終了する仕組みを作ります。

例:countが特定の値に達したらループを終了するように設定します。

while文の条件式でエラーが出るのはなぜ?

while文の条件式でエラーが出る主な原因は以下の通りです。

  • 構文エラー: 条件式の書き方が間違っている場合、例えば[]の数が合わない、またはスペースが不足しているとエラーが発生します。
  • 変数の未定義: 使用している変数が未定義の場合、条件式が正しく評価されずエラーになります。
  • 数値と文字列の比較: 数値の比較を行う際に、文字列比較の演算子=!=を使用するとエラーになります。

数値比較には-eq-neを使用してください。

while文の中で変数を使う際の注意点は?

while文の中で変数を使用する際には、以下の点に注意が必要です。

  • 変数の初期化: ループを開始する前に変数を初期化しておくことが重要です。

未初期化の変数を使用すると、予期しない動作を引き起こす可能性があります。

  • 変数のスコープ: 変数のスコープに注意し、必要に応じてグローバル変数やローカル変数を使い分けます。
  • 変数の更新: ループ内で変数を適切に更新し、条件が正しく評価されるようにします。

特に、カウンタやフラグを使用する場合は、更新を忘れないようにしましょう。

例:カウンタ変数を使用する場合、ループ内で必ず更新処理を行います。

まとめ

この記事では、Bashのwhile文の基本的な使い方から、実用的な応用例、他の制御構文との組み合わせまで幅広く解説しました。

特に、無限ループの作成や制御、複数の条件を使ったループ処理、ユーザー入力を待つループなど、実際のシナリオで役立つテクニックに焦点を当てています。

これを機に、while文を活用して自分のスクリプトをより効率的に作成し、さまざまな処理を自動化してみてください。

  • URLをコピーしました!
目次から探す