[linux] シェルのwhile文の使い方 – 繰り返しコマンド処理する
Linuxのシェルでwhile
文は、条件が真である間、指定したコマンドを繰り返し実行するために使用されます。
基本的な構文は以下の通りです:
while [ 条件 ]; do
コマンド
done
[ 条件 ]
の部分で条件を評価し、条件が真であればdo
以降のコマンドが実行されます。
条件が偽になるとループが終了します。
例えば、カウンタを使って特定の回数だけループを実行する場合や、ファイルの内容を1行ずつ処理する場合などに利用されます。
- while文の基本構文と使い方
- 条件式の書き方と注意点
- 無限ループの作成と制御方法
- 他の制御構文との組み合わせ
- 実用的な応用例の紹介
while文の基本構文
while文の基本的な書き方
while
文は、指定した条件が真である限り、繰り返し処理を実行するための構文です。
基本的な書き方は以下の通りです。
while [ 条件 ]; do
# 繰り返し実行するコマンド
done
この構文では、条件
が真である限り、do
とdone
の間に記述されたコマンドが繰り返し実行されます。
条件式の書き方
条件式は、[
と ]
で囲まれた部分に記述します。
条件式には、数値の比較や文字列の比較、ファイルの存在確認などが使用できます。
以下は、いくつかの条件式の例です。
条件式 | 説明 |
---|---|
-eq | 等しい |
-ne | 等しくない |
-lt | より小さい |
-le | 以下 |
-gt | より大きい |
-ge | 以上 |
-e | ファイルが存在するか確認 |
doとdoneの役割
do
とdone
は、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
このように、break
とcontinue
を使うことで、無限ループの制御が柔軟に行えます。
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
文を使うことで、さまざまな応用例を実装することができます。
よくある質問
まとめ
この記事では、Bashのwhile
文の基本的な使い方から、実用的な応用例、他の制御構文との組み合わせまで幅広く解説しました。
特に、無限ループの作成や制御、複数の条件を使ったループ処理、ユーザー入力を待つループなど、実際のシナリオで役立つテクニックに焦点を当てています。
これを機に、while
文を活用して自分のスクリプトをより効率的に作成し、さまざまな処理を自動化してみてください。