条件分岐 if

条件分岐 if とは

if文を使って、条件によって実行するコマンドを切り替える方法をターミナルで体験します。本レッスンでは、条件分岐 if の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

なぜ重要か

単に上から下にコマンドを並べるだけでは「もしファイルが存在しなかったら作成する」「環境変数が未設定なら中断する」といった現実的な判断ができません。シェルスクリプトに if を入れることで、状況に応じた振る舞いを表現できるようになり、ようやく「壊れない自動化」と呼べるレベルに到達します。デプロイスクリプトやヘルスチェック、cron で叩く監視スクリプトなど、条件分岐が登場しない実用スクリプトはほぼ存在しません。

if の基本構文

ターミナル

if [[ 条件 ]]; then # 条件が真のとき実行 elif [[ 別の条件 ]]; then # 上が偽で、ここが真のとき else # どれにも当てはまらないとき fi

ブロックを閉じる fi は if を逆さに書いたもの、というのが伝統的な書き方です。then の前のセミコロンを忘れがちなので注意してください。

条件の書き方

bash では条件式に [ ... ] (古い POSIX 形式) と [[ ... ]] (bash 拡張) の 2 種類があります。新しいスクリプトでは扱いが安全な [[ ... ]] を推奨します。

ターミナル

name="Tanaka" if [[ "$name" == "Tanaka" ]]; then echo "hello Tanaka" fi

よく使う比較演算子は次の通りです。

演算子用途
== / !=文字列の等価 / 非等価
-eq / -ne数値の等価 / 非等価
-lt / -le / -gt / -ge数値比較
-z文字列が空かどうか
-n文字列が空でないか
-eファイルやディレクトリが存在するか
-f通常ファイルが存在するか
-dディレクトリが存在するか
-r / -w / -x読み書き実行可能か

数値比較と文字列比較の使い分け

ターミナル

age=30 if [[ "$age" -ge 20 ]]; then echo "adult" fi name="alice" if [[ "$name" == "alice" ]]; then echo "hi alice" fi

数値は -eq 系、文字列は == 系を使うのが原則です。== で数値同士を比べても字面が一致すれば真になりますが、"05"5 が等価にならないなどハマりやすいので使い分けは意識します。

分岐の流れ

diagram (will load when visible)

どの分岐に入っても最後の fi で合流し、その後の処理に進みます。

ファイル・ディレクトリの存在チェック

ターミナル

#!/bin/bash file="/tmp/data.txt" if [[ -f "$file" ]]; then echo "$file exists" else echo "$file not found" touch "$file" fi

-f は通常ファイル、-d はディレクトリ、-e はどちらでも存在チェックに使えます。デプロイ前にディレクトリが揃っているかを if で確かめてから本処理に進む、という防御的な書き方は実務で頻出します。

終了ステータスでの分岐

コマンドが成功すれば $? は 0、失敗すれば非ゼロの値になります。これを直接 if で評価できます。

ターミナル

if grep -q "ERROR" /var/log/app.log; then echo "エラーが見つかった" else echo "問題なし" fi

grep -q は出力を抑えて終了ステータスだけ返すので、こうした条件分岐に向いています。curl --fail と組み合わせれば、HTTP 4xx/5xx を if で検知する監視スクリプトが書けます。

シェルでは「コマンドの成功/失敗で分岐する」のが定石です。文字列比較に持ち込まなくても、grep -q, curl --fail, test, [[ ... ]] などコマンドの戻り値をそのまま if に渡せます。これを意識すると bash らしいスッキリした書き方になります。

複合条件

ターミナル

if [[ -f "$file" && -r "$file" ]]; then echo "読み込めるファイル" fi if [[ "$mode" == "dev" || "$mode" == "staging" ]]; then echo "非本番" fi

&& は AND、|| は OR で組み合わせられます。[[ ... ]] の中ではこれらの演算子が安全に使えるのも bash 拡張の利点です。

case による多分岐

選択肢が増えるときは case の方が読みやすいことがあります。

ターミナル

case "$1" in start) echo "起動中" ;; stop) echo "停止中" ;; restart) echo "再起動" ;; *) echo "使用法: $0 start|stop|restart" ;; esac

シェル風の switch 文として、サービス管理スクリプトの定番のパターンです。

ifcase の境界は「3 つ以上の値を平等に判定するなら case、それ以外は if」が目安です。case はワイルドカード * でデフォルト分岐を書けるため、CLI のサブコマンド処理に向いています。

まとめ

  • if [[ 条件 ]]; then ... fi が基本形
  • [[ ... ]] の bash 拡張形式が安全で読みやすい
  • 文字列は ==, 数値は -eq 系で比較する
  • -f, -d, -e などでファイル存在を判定できる
  • コマンドの終了ステータスをそのまま条件に使える
  • 多分岐は case の方が見通しが良くなる

次のレッスン

次は ループ処理 for, while で、if文を使って、条件によって実行するコマンドを切り替える方法をターミナルで体験します を学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. if 文 の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. if 文 とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

課題

  1. if 文を使う
  2. 20 以上で adult を出力する

ヒント

script.sh
script.sh
学習モード
script.sh
ターミナル出力