【Bash講座 第8回】スクリプトに「知能」を与える!条件分岐(if文)完全攻略

bash講座

【Bash講座 第8回】スクリプトに「知能」を持たせよう!条件分岐(if文)の極意

こんにちは!「リナックス先生」です。
前回は、コマンドをファイルにまとめて自動実行する「シェルスクリプト」の第一歩を踏み出しました。
コウ君、宿題のバックアップスクリプトは作ってみた?

コウ君

先生!作ってみたんですけど…失敗しました。
「バックアップ先のディレクトリ」を作るのを忘れて実行したら、エラーが出てファイルが保存されなかったんです。
「もしディレクトリがなかったら勝手に作る」みたいに、気を利かせてくれたらいいのに!

リナックス先生

いい失敗ね! それこそがプログラミングが必要な理由よ。
ただ上から順に実行するだけじゃなくて、状況に合わせて動きを変える。
それを実現するのが「条件分岐(if文)」よ。
今回は、スクリプトに「判断する力(知能)」を与えて、エラーに強い堅牢なツールに進化させましょう!

第8回となる今回は、プログラミングの基本中の基本であるif文と、Linux特有の「テストコマンド」について解説します。
これを使えば、「rootユーザーじゃなければ実行しない」「ファイルが既にあるなら上書きしない」といった、安全なスクリプトが書けるようになります。

本講座のカリキュラム(全12回)

AlmaLinux 9 (RHEL 9互換) 環境を前提に、基礎から応用までステップバイステップで進めます。

  1. Bash入門編:シェルとカーネルの関係、CUIの哲学、環境構築
  2. ファイル操作の極意:絶対パス・相対パスと「ワイルドカード」の魔術
  3. 権限(パーミッション)とユーザー:chmod, chown, sudoの仕組みを完全理解
  4. 入出力リダイレクトとパイプ:Linuxの真骨頂!コマンド同士を連携させる技術
  5. テキスト処理の基本:cat, head, tail, less…ファイルの中身を覗く道具たち
  6. 最強のエディタ「Vi/Vim」入門:サーバー内でテキストを編集する必須スキル
  7. シェルスクリプトの第一歩:ファイルにまとめて自動実行!変数と引数の基礎
  8. 【今回】条件分岐(if文):サーバーの状態を見て「判断」できるスクリプトを作る
  9. 繰り返し処理(for/while文):面倒な単純作業を1秒で終わらせるループ処理
  10. テキスト処理の応用:grep, sed, awk…ログ解析の達人になるための三種の神器
  11. 実践・自動化スクリプト:バックアップと監視を自動化し、Cronで定期実行する
  12. 総仕上げ:自作スクリプトの集大成と、エンジニアとしての歩き方

1. if文の基本構文:スペースに命をかけろ!

まずは形から入りましょう。
Bashのif文は、他のプログラミング言語(PythonやJavaScriptなど)とは少し見た目が違います。

基本の形

if [ 条件式 ]; then
    # 条件が合致した時の処理
    echo "条件OKです"
else
    # 条件が合致しなかった時の処理
    echo "条件NGです"
fi

⚠️ 絶対に間違えてはいけないポイント

[ 条件式 ] の中にあるスペースに注目してください。
[ の直後と、] の直前には、必ず半角スペースが必要です。

  • if [$a = $b]; then (くっついている:エラー!)
  • if [ $a = $b ]; then (離れている:正解!)

実はこの [ という記号、ただの括弧ではなく「test」という名前のコマンドなのです。
「testコマンドに引数を渡す」と考えれば、スペースが必要な理由がわかりますね。

実際に書いてみよう

変数の中身をチェックする簡単なスクリプト check_name.sh を作ってみましょう。

#!/bin/bash

NAME="Linux"

if [ "$NAME" = "Linux" ]; then
    echo "あなたはLinuxですね!"
else
    echo "あなたは誰ですか?"
fi

実行結果:

[root@localhost ~]# ./check_name.sh
あなたはLinuxですね!

2. 数値を比較する:大なり小なり記号は使えない?

ここがBashの少しややこしいところです。
数値の比較には >< などの記号は使いません(これらはリダイレクトとして解釈されてしまうからです)。
代わりに、アルファベットの略語を使います。

演算子 英語の意味 日本語
-eq equal 等しい
-ne not equal 等しくない
-gt greater than より大きい ( > )
-lt less than より小さい ( < )
-ge greater or equal 以上 ( >= )
-le less or equal 以下 ( <= )

数値比較のスクリプト例

引数で渡された数字が10より大きいか判定する check_num.sh です。

#!/bin/bash

# $1 は実行時に渡された1つ目の引数
NUM=$1

if [ "$NUM" -gt 10 ]; then
    echo "$NUM は 10 より大きいです"
else
    echo "$NUM は 10 以下です"
fi

実行結果:

[root@localhost ~]# ./check_num.sh 15
15 は 10 より大きいです
[root@localhost ~]# ./check_num.sh 5
5 は 10 以下です

3. 文字列を比較する:クォートを忘れずに

文字列の比較は、直感的でわかりやすい記号を使います。

  • = : 文字列が一致する
  • != : 文字列が一致しない
  • -z : 文字列が空(長さがゼロ)である
  • -n : 文字列が入っている(長さがゼロではない)
コウ君

先生、なんでさっきの例で if [ "$NAME" = "Linux" ] って、変数にダブルクォートをつけてたんですか?
if [ $NAME = Linux ] じゃダメなんですか?

リナックス先生

鋭いわね! それは「変数が空っぽだった時のため」よ。
もし $NAME が空の状態でクォートなしだと、Bashは if [ = Linux ] と解釈してしまうの。
左側がないから「構文エラー」になっちゃうわ。
"$NAME" と囲っておけば if [ "" = "Linux" ] と解釈されて、正しく「不一致」と判定されるのよ。

4. ファイルの状態を調べる:サーバー管理の最重要項目

シェルスクリプトで最もよく使うのが、「ファイルやディレクトリが存在するか?」というチェックです。
これを覚えると、コウ君の「ディレクトリがなくて失敗」という事故を防げます。

演算子 意味 使い所
-e ファイル名 存在する (exist) ファイルでもディレクトリでも、とにかくあればOK
-f ファイル名 ファイルである (file) ディレクトリではなく普通のファイルか確認
-d ディレクトリ名 ディレクトリである (directory) 保存先フォルダがあるか確認
-r ファイル名 読み取り可能 (readable) catする前に確認
-w ファイル名 書き込み可能 (writable) ログを保存する前に確認

実践:ディレクトリがなければ作るスクリプト

これがコウ君が欲しがっていた機能です! smart_backup.sh を作りましょう。

#!/bin/bash

BACKUP_DIR="/var/backup"

# ディレクトリがあるかチェック
if [ -d "$BACKUP_DIR" ]; then
    echo "保存先ディレクトリを確認しました。"
else
    echo "保存先ディレクトリがありません。作成します..."
    mkdir -p "$BACKUP_DIR"
fi

# バックアップ処理(今回はダミー)
echo "バックアップを実行中..."
# tar czf ... などの処理

これを実行すれば、初回はディレクトリを作成し、2回目以降は何もしないという「賢い」動作になります。

5. 終了ステータス「$?」:コマンドの成否を判定する

Linuxのコマンドは、実行が終わるとこっそり「終了ステータス (Exit Status)」という数字を残します。
直前のコマンドの結果は、特殊変数 $? に入っています。

  • 0 : 成功 (Success)
  • 0以外 : 失敗 (Error)
コウ君

えっ!? 普通のプログラミングだと、1(True)が成功で、0(False)が失敗じゃないんですか?逆なんですか?

リナックス先生

そうなの。ここが最大の落とし穴よ。
Linuxの世界では「エラーなし(0)」が正常
エラーには「ファイルがない(1)」「権限がない(2)」といろんな種類があるから、0以外は全部異常なの。

コマンドの成功/失敗で分岐する

実は if 文は、直接コマンドを実行して、その成功(0)/失敗(非0)を判定できます。
[ ] を使わない書き方です。

#!/bin/bash

# pingコマンドでGoogleに繋がるか確認(-c 1 は1回だけ試すオプション)
if ping -c 1 google.com > /dev/null; then
    echo "インターネットに繋がっています!"
else
    echo "ネットワークエラーです!"
fi

このように書くと、ping が成功すれば then 以下が、失敗すれば else 以下が実行されます。
サーバー監視スクリプトなどで非常によく使うテクニックです。

6. 論理演算子:ANDとOR

複数の条件を組み合わせたい時もありますよね。

  • && (AND) : 両方ともOKなら
  • || (OR) : どちらか片方でもOKなら
  • ! (NOT) : 条件を反転(~でなければ)
#!/bin/bash

FILE="test.txt"

# ファイルが存在し、かつ(-a)、書き込み可能(-w)なら
if [ -e "$FILE" ] && [ -w "$FILE" ]; then
    echo "書き込みOKです"
fi

# userが root ではない(!=)場合
if [ "$USER" != "root" ]; then
    echo "rootユーザーで実行してください!"
    exit 1  # 異常終了させる
fi

次回予告:単純作業は機械にやらせろ

第8回は、スクリプトに知能を与える「条件分岐」について解説しました。
数値の比較方法(-eq, -gt)や、ファイルチェック(-d, -f)、そして終了ステータス(0が成功)など、覚えることは多かったですが、これらは一生使う知識になります。

次回は、プログラミングのもう一つの醍醐味、「繰り返し処理(ループ)」です。
「ディレクトリにある100個のファイルを全部変換する」「サーバーリストに載っている全台に同じ設定をする」といった、人間がやると日が暮れる作業を、for 文や while 文を使って一瞬で終わらせる魔法を伝授します。

リナックス先生

次回までに、今回の if 文を使って
「引数でファイル名を指定し、そのファイルが存在すれば中身を表示、なければエラーを表示するスクリプト」
を作ってみてね。これができれば立派なツール開発者よ!

▼スクリプトの実験場に最適!推奨VPS

【2026年最新】Linuxサーバー構築におすすめのVPS比較3選!現役エンジニアが速度とコスパで厳選
Linuxの勉強、まだ「自分のPC」でやって消耗していませんか?「Linuxを覚えたいけど、環境構築でエラーが出て先に進めない…」「VirtualBoxを入れたらパソコンが重くなった…」これは、Linux学習を始める9割の人がぶつかる壁です...

コメント