Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

実践編:制御構文と条件分岐・繰り返し

条件判定を行うテスト構文([[ ... ]])、if や case による条件分岐、および for や while を用いた繰り返し処理の設計方法を解説します。

テスト構文(条件判定)

Bash では条件を判定する際に角括弧を使用します。従来の POSIX 標準である [ ... ](test コマンド)に加え、Bash 拡張の [[ ... ]] が利用可能です。

[[ ... ]] は単語分割やワイルドカードの不要な展開を防ぎ、正規表現もサポートするため、Bash スクリプトでは基本的に [[ ... ]] の使用が推奨されます。

» 文字列と数値の比較

Bash では文字列比較と数値比較で異なる演算子を使用します。

判定対象演算子例
文字列が一致==[[ "$name" == "Alice" ]]
文字列が不一致!=[[ "$name" != "Bob" ]]
空文字列(長さ0)-z[[ -z "$input" ]]
非空文字列-n[[ -n "$input" ]]
数値が等しい-eq[[ "$count" -eq 10 ]]
数値が大きい-gt[[ "$size" -gt 100 ]]
数値が小さい-lt[[ "$age" -lt 20 ]]

» ファイルとディレクトリの判定

ファイルシステムの検証で頻出する主要なテスト演算子です。

# 通常ファイルが存在するか確認
if [[ -f "/etc/hosts" ]]; then
    echo "hosts file exists."
fi

# ディレクトリが存在するか確認
if [[ -d "./build" ]]; then
    echo "build dir exists."
fi

# 実行権限があるか確認
if [[ -x "./deploy.sh" ]]; then
    echo "deploy.sh is executable."
fi

» 正規表現マッチング(=~)

=~ 演算子を用いて、入力値が正規表現パターンに合致するかを判定できます。マッチした部分は組み込み配列変数 BASH_REMATCH に格納されます。

INPUT="port:8080"

if [[ "$INPUT" =~ ^port:([0-9]+)$ ]]; then
    PORT_NUM="${BASH_REMATCH[1]}"
    echo "Matched port: $PORT_NUM"
fi

条件分岐(if と case)

状況に応じて異なる処理を実行するための構文です。

» if / elif / else / fi

STATUS=200

if [[ "$STATUS" -eq 200 ]]; then
    echo "Success: OK"
elif [[ "$STATUS" -eq 404 ]]; then
    echo "Error: Not Found"
else
    echo "Unexpected status code: $STATUS"
fi

» case / in / esac

コマンドライン引数の処理や、特定パターンの分類には case 文が適しています。各パターンの終端にはセミコロンを2つ(;;)記述します。

ACTION="$1"

case "$ACTION" in
    start)
        echo "Starting service..."
        ;;
    stop)
        echo "Stopping service..."
        ;;
    restart|reload)
        echo "Restarting service..."
        ;;
    *)
        echo "Usage: $0 {start|stop|restart}" >&2
        exit 1
        ;;
esac

繰り返し構文(for と while)

連続したデータやファイルを順次処理するループ構文です。

» for ループ

配列の要素やワイルドカードで展開されたファイル一覧を走査します。

# 配列の全要素をループ
REGIONS=("ap-northeast-1" "us-west-2" "eu-west-1")

for region in "${REGIONS[@]}"; do
    echo "Checking region: $region"
done

# C 言語スタイルの数値ループ
for ((i = 1; i <= 5; i++)); do
    echo "Step: $i"
done

» while ループとファイルの1行読み込み

条件が真である間、処理を繰り返します。ファイルを1行ずつ安全に読み込む定石パターンとして read -r との組み合わせが使われます。

# ファイルから1行ずつ読み込んで処理
while IFS= read -r line; do
    echo "Processing: $line"
done < "./data.txt"

-r オプションはバックスラッシュのエスケープ解釈を無効化し、IFS= は前後の不要な空白トリムを防止します。