はじめに

こんにちは!今回はwhile文について解説します。

whileは条件が真(true)の間、処理を繰り返すための構文です。forと似てるんですけど、回数が決まってない時とか、条件次第で繰り返したい時に使います。

while文とは

whileは、指定した条件が真の間、処理を繰り返し続けるための制御構文です。

「ファイルが見つかるまで待つ」とか「ユーザーが’quit’と入力するまで続ける」みたいな、終わりが明確じゃない処理に便利です。

基本構文

1
2
3
while [ 条件 ]; do
    # 条件が真の間、繰り返し実行する処理
done

使用例

例1: カウンターのループ

1
2
3
4
5
6
count=1

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

実行結果:

1
2
3
4
5
カウント: 1
カウント: 2
カウント: 3
カウント: 4
カウント: 5

例2: 無限ループ

1
2
3
4
while true; do
    echo "無限ループ中... (Ctrl+Cで終了)"
    sleep 1
done

trueは常に真なので、無限に繰り返します。Ctrl+Cで止められます。

例3: ファイルを1行ずつ読む

1
2
3
while read line; do
    echo "行: $line"
done < file.txt

ファイルの内容を1行ずつ処理できます。これめっちゃよく使います。

例4: ユーザー入力でループ

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
while true; do
    read -p "コマンドを入力 (quitで終了): " cmd

    if [ "$cmd" = "quit" ]; then
        echo "終了します"
        break
    fi

    echo "入力: $cmd"
done

実行例:

1
2
3
4
5
6
コマンドを入力 (quitで終了): hello
入力: hello
コマンドを入力 (quitで終了): test
入力: test
コマンドを入力 (quitで終了): quit
終了します

例5: ファイルが作られるまで待つ

1
2
3
4
5
6
7
8
file="signal.txt"

while [ ! -f "$file" ]; do
    echo "ファイルを待機中: $file"
    sleep 2
done

echo "ファイルが見つかりました!"

ファイルが作られるまでループし続けます。

例6: 数値を減らしていく

1
2
3
4
5
6
7
8
9
count=5

while [ $count -gt 0 ]; do
    echo "残り: $count"
    sleep 1
    count=$((count - 1))
done

echo "完了!"

実行結果:

1
2
3
4
5
6
残り: 5
残り: 4
残り: 3
残り: 2
残り: 1
完了!

カウントダウンみたいなのも作れます。

Tips・注意点

  • 無限ループに注意: 条件が常に真だと永遠に止まりません

    1
    2
    3
    4
    
    # これは永遠に止まらない
    while true; do
        echo "止まらない"
    done
    

    必ずCtrl+Cで止められるようにしておくか、breakで抜けられるようにしましょう。

  • break と continue: ループを制御できます

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    while true; do
        read -p "入力: " input
        if [ "$input" = "exit" ]; then
            break  # ループを抜ける
        fi
        if [ -z "$input" ]; then
            continue  # 空なら次のループへ
        fi
        echo "処理: $input"
    done
    
  • ファイル読み込みの注意: パイプ使うと変数のスコープに注意が必要

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    # これだと変数が保持されない
    cat file.txt | while read line; do
        count=$((count + 1))
    done
    echo $count  # 空になる
    
    # こっちが正しい
    while read line; do
        count=$((count + 1))
    done < file.txt
    echo $count  # ちゃんと値が入ってる
    
  • sleep で間隔をあける: 連続実行しすぎないように

    1
    2
    3
    4
    
    while true; do
        # 何か処理
        sleep 1  # 1秒待つ
    done
    

実践的な使い方

監視スクリプト

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/bin/bash

log_file="/var/log/app.log"

while true; do
    if grep -q "ERROR" "$log_file"; then
        echo "エラーを検出しました!"
        # 通知処理など
    fi
    sleep 10  # 10秒ごとにチェック
done

ログファイルを監視し続けるスクリプトとか。

プロセス待機

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/bin/bash

process="myapp"

while pgrep "$process" > /dev/null; do
    echo "プロセス実行中: $process"
    sleep 5
done

echo "プロセスが終了しました"

特定のプロセスが終わるまで待つとか。

ディスク使用率の監視

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!/bin/bash

threshold=80

while true; do
    usage=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')

    if [ $usage -gt $threshold ]; then
        echo "警告: ディスク使用率が${usage}%です"
    fi

    sleep 60  # 1分ごとにチェック
done

対話型メニュー

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/bash

while true; do
    echo "=== メニュー ==="
    echo "1. ファイル一覧"
    echo "2. ディスク使用量"
    echo "3. 終了"
    read -p "選択: " choice

    case $choice in
        1)
            ls -la
            ;;
        2)
            df -h
            ;;
        3)
            echo "終了します"
            break
            ;;
        *)
            echo "無効な選択です"
            ;;
    esac

    echo
done

簡単な対話型メニューも作れます。

リトライ処理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/bash

max_retry=3
count=0

while [ $count -lt $max_retry ]; do
    echo "接続試行中... ($((count + 1))/$max_retry)"

    if ping -c 1 google.com > /dev/null 2>&1; then
        echo "接続成功!"
        break
    fi

    count=$((count + 1))
    sleep 2
done

if [ $count -eq $max_retry ]; then
    echo "接続に失敗しました"
    exit 1
fi

失敗したら何回か再試行する処理とか。

ファイル処理(行ごと)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/bin/bash

total=0

while read line; do
    # 数値のみの行を合計
    if [[ "$line" =~ ^[0-9]+$ ]]; then
        total=$((total + line))
    fi
done < numbers.txt

echo "合計: $total"

まとめ

今回はwhile文について解説しました。

ポイント:

  • whileは条件が真の間、処理を繰り返す
  • 回数が決まってない処理に便利
  • breakでループを抜けられる
  • 無限ループに注意(Ctrl+Cで止められるようにしておく)

forは回数が決まってる時、whileは条件次第で繰り返したい時って感じで使い分けます。監視スクリプトとか、待機処理とか、色々使えるので覚えておくと便利ですよ。

次回もLinuxコマンドの学習を続けていきましょう!