Shell の基礎知識

【Shellの基礎知識】条件分岐『if』『case』の使い方を解説

条件分岐

「Shellスクリプトを学ぶ上で、条件分岐の理解は欠かせません。『if』や『case』を活用することで、プログラムに柔軟性と効率性を持たせることができます。しかし、初心者にとってはその構文や使い分けが少し難しく感じるかもしれません。本記事では、条件分岐の基本から実践的な応用例まで、初心者にもわかりやすく解説します。シンプルな例を通して、スクリプト作成の第一歩を踏み出しましょう!

Shellスクリプトの条件分岐とは?

Shellスクリプトにおける条件分岐は、プログラムの処理を状況に応じて分岐させるための重要な仕組みです。これにより、特定の条件を満たした場合にのみ特定の処理を実行したり、複数の選択肢から適切な処理を選択することが可能になります。

条件分岐は、プログラムの柔軟性を高め、エラーの回避や効率的な処理を実現する上で欠かせない要素です。たとえば、以下のような場面で活用されます。

条件分岐の使用場面

  • エラーハンドリング
    ファイルの存在確認やアクセス権のチェックを行い、エラーが発生した際に適切なメッセージを表示したり処理を中断します。

if [ -f /path/to/file ]; then
  echo "File exists"
else
  echo "File not found"
fi

  • ユーザー入力の処理
    ユーザーが入力した値に基づいて処理を切り替えます。

case $input in
  start)
    echo "Starting process"
    ;;
  stop)
    echo "Stopping process"
    ;;
  *)
    echo "Invalid input"
    ;;
esac

  • システムの状態確認
    CPU使用率やディスク容量などをチェックし、異常値を検出した場合に警告を出す。

if [ $(df / | tail -1 | awk '{print $5}' | sed 's/%//') -gt 80 ]; then
  echo "Disk usage high"
fi

これらの例からわかるように、条件分岐を利用することで、スクリプトの動作を動的に制御し、実用的な機能を実現できます。

本記事を通じて、条件分岐の基本をしっかりと理解し、実際の場面で活用できるスクリプト作成スキルを身につけましょう。

『if』文の基本構文と使い方

『if』文は、Shellスクリプトで条件を評価し、それに基づいて特定の処理を実行するために使用されます。以下は基本的な構文です。

『if』文の構文

『if』文は、特定の条件を評価し、その条件が「真」である場合にのみ処理を実行する構造を提供します。基本的な条件分岐に使用されるこの文法は、シェルスクリプトで柔軟なロジックを構築するための第一歩です。

たとえば、ファイルやディレクトリの存在確認といった簡単なチェックに活用できます。

if

上記イメージの判定は、「真(true)」の時のみ、アクション1を実行します。それ以外はスルーします。

コマンドの書式

if  [ 条件式 ];  then
    アクション1
fi

以下は具体的な例です。

if [ -f /path/to/file ]; then
  echo "ファイルが存在します。"
fi

この例では、指定されたファイルが存在する場合に「ファイルが存在します。」と表示されます。

『if-else』文の構文

『if-else』文は、『if』文を拡張し、条件が「真」でない場合に実行する処理を指定できる構文です。この文法を使うことで、状況に応じた適切な処理を分岐させることが可能になります。

エラー時の代替処理や、条件が満たされない場合の処理をスクリプトに組み込む際に役立ちます。

if-else

書式は、下記の様になります。下記の書式では、[ ]の中の条件式の結果が真となる場合にアクション1を実行し、それ以外の場合はアクション2を実行します。

コマンドの書式

if  [ 条件式 ];  then
    アクション1
else
    アクション2
fi

『if』文は単純な条件評価だけでなく、複数の条件を評価するために elif を使用して拡張することができます。単純条件の例として、ディレクトリの存在をチェックするスクリプトを以下に示します。

if [ -d /path/to/directory ]; then
  echo "ディレクトリが存在します。"
else
  echo "ディレクトリが存在しません。"
fi

『if-elif-else』文の構文

『if-elif-else』文は、複数の条件を評価して、それぞれに応じた処理を実行するための構文です。この文法を活用すると、複数の選択肢がある場合でも効率的にロジックを構築できます。

特定の条件を順に評価し、最初に「真」となる条件を満たした場合の処理を実行します。

if-elif-else

コマンドの書式

if  [ 条件式 ];  then
    アクション1
elif  [ 条件式 ];  then
    アクション2
else
    アクション3
fi

引数に指定した"test.txt"の属性が、「ファイルなのか」「ディレクトリなのか」、もしくはどちらでもない「オブジェクトなのか」を判定するシェルスクリプトを作成してみます。

下記のロジックをコンソールへ入力してみましょう。

# 予め"test.txt"ファイルを作成しておく
touch test.txt

str1="これはファイルです。"
str2="これはディレクトリです。"
str3="不明なオブジェクトです。判定できません。"

judge_type (){
    var=${1}
    if [ -f ${var} ]; then
        echo " [${var}] : ${str1}"
    elif [ -d ${var} ]; then
        echo " [${var}] : ${str2}"
    else
        echo " [${var}] : ${str3}"
    fi
}

下記は実行結果です。

引数で指定した"test.txt"の属性は、ファイルであることが分かりました。

ネストした条件分岐

『if』文はネスト構造を利用して、より複雑な条件を処理することも可能です。ただし、ネストが深くなるとコードの可読性が低下するため、必要に応じてスクリプトをリファクタリングすることが重要です。

以下はネスト条件分岐の例です

if [ -f /path/to/file ]; then
  echo "ファイルが存在します。"
  if [ -w /path/to/file ]; then
    echo "ファイルに書き込みが可能です。"
  else
    echo "ファイルに書き込みができません。"
  fi
  else
    echo "ファイルが存在しません。"
fi

この例では、ファイルが存在する場合にさらに書き込み可能かどうかをチェックしています。ネスト構造を使用する際は、条件を単純化したり、スクリプトを分割して可読性を保つことを心がけましょう。

『case』文の基本構文と使い方

『case』文は、Shellスクリプトで複数の条件に応じた処理を簡潔に記述するために使用されます。条件を複数並べる場合に特に便利で、スクリプトを簡潔で読みやすく保つのに役立ちます。

『case』文の構文

case文は1つの変数だけで複数の条件分岐を設定出来るのが特徴です。変数の値がパターン条件にマッチした時にマッチした条件の処理を実行します。

case "$変数" in
パターン1)
  # パターン1にマッチした場合の処理
  ;;
パターン2)
  # パターン2にマッチした場合の処理
  ;;
*)
  # どのパターンにもマッチしない場合の処理
  ;;
esac

ちなみに、いくつか注意点がありますので下記のリストにまとめてみました。

  • 処理の終了には「;;」を記述すること。
  • case文の終わりにはesacと記述すること。
  • 変数が全ての条件式にマッチしなかったときはなにも処理されません。

注意点に挙げるほどではないですが、複数の処理をさせたい場合は改行をすることで後で読み返したときに可読性が高くなります。

コマンドの書式

case  値  in
    パターン条件1)  処理1 ;;
    パターン条件2)  処理2 ;;
    パターン条件3)  処理3 ;;
esac

「Case」文も「if」文同様に、「ネスト(入れ子)」構造にすることが可能です。

キーボード入力を受け付けるロジックになるため、少し実践的に「シェルスクリプト」ファイルとして作成します。判定には「Case」文を使用します。

これから作成する「シェルスクリプト」は、キーボードから入力された引数が「アルファベット」「数値」「それ以外」のいずれかに該当するモノかを判定するロジックです。

str1="入力されたのはアルファベットですね。"
str2="入力されたのは数字ですね。"
str3="入力された文字は不明な文字種です。"

read -p "文字を入力してください。:" input

case "${ input }" in
    [a-zA-Z] ) echo "${ str1 }" ;; 👈(1)
         [0-9] ) echo "${ str2 }" ;; 👈(2)
                * ) echo "${ str3 }" ;; 👈(3)
esac

1:[a-zA-Z]は、変数の値がアルファベットの小文字と大文字のときにマッチします。
2:[0 - 9]は、変数の値が数字の0~9のときにマッチします。
3:*は、すべての文字列にマッチします。

パターン条件に記述可能なワイルドカードは、以下の意味を持ちます。

*   :文字列全部(文字がなくても)に合致する
?   :1文字に合致する
[...]     :[ ]の中に含まれる文字のどれか1つ
[!...]       :[ ]に含まれない文字に合致する
                複数の条件を指定することも可能です。

ちなみに、下記のコマンドでプロンプトからの引数入力を要求します。

# プロンプトからの引数入力を要求
read -p "文字を入力してください。:" input

『case』文と『if』文の使い分け

『case』文と『if』文はどちらも条件分岐に使用されますが、それぞれ適した使いどころがあります。

『case』文が適している場面

『case』文は、特定の値や文字列に対して複数のパターンを評価する場合に最適です。たとえば、ユーザー入力やメニュー選択に応じて処理を切り替える場合に便利です。コードが簡潔で読みやすくなります。

case $color in
  red)
    echo "赤色を選択しました。"
    ;;
  blue)
    echo "青色を選択しました。"
    ;;
  green)
    echo "緑色を選択しました。"
    ;;
  *)
    echo "無効な色です。"
    ;;
esac

『if』文が適している場面

『if』文は、条件が数値の比較や論理演算のような複雑な評価を必要とする場合に適しています。特定の条件が成立する場合にのみ処理を行うシンプルな構造にも適用可能です。

if [ $value -gt 10 ]; then
  echo "値は10より大きいです。"
elif [ $value -eq 10 ]; then
  echo "値は10です。"
else
  echo "値は10より小さいです。"
fi

  • 条件が単純で、特定の値や文字列に基づく処理が多い場合は『case』文。
  • 条件が複雑で、数値や論理演算を含む場合は『if』文。

両者を適切に使い分けることで、スクリプトの可読性と効率性を向上させることができます。

条件分岐の実践とよくある疑問への回答

条件分岐はShellスクリプトの中核となる機能であり、効率的な処理を実現するために欠かせない要素です。

本セクションでは、条件分岐を活用した実用的なスクリプト例を紹介するとともに、初心者が抱えやすい疑問点についても解説します。

具体的な例とヒントを通じて、条件分岐の理解を深め、より実践的なスクリプトを作成できるようになりましょう。

条件分岐を使った実用スクリプト例

条件分岐を適切に活用することで、システム管理やユーザー操作を効率化する強力なスクリプトを作成できます。

本セクションでは、条件分岐を使用した3つの実用的なスクリプト例を紹介します。これらの例を通じて、現場で役立つスクリプト作成スキルを習得しましょう。

システムサービスの管理スクリプト

システムサービスの起動、停止、再起動を自動化するスクリプトは、日常の運用を効率化する上で非常に重要です。

ここでは、『if』文と『case』文を活用して、ユーザー入力に応じた操作を行うスクリプトの実装例を紹介します。

#!/bin/bash

サービス名と操作を取得

read -p "サービス名を入力してください: " service
read -p "操作を選択してください (start/stop/restart): " action

# サービス名が指定されていない場合のエラー処理
if [ -z "$service" ]; then
  echo "エラー: サービス名が指定されていません。"
  exit 1
fi

# 操作に応じた処理
case $action in
  start)
    echo "$service を開始します…"
    # サービスを開始するコマンドをここに追加
    ;;
  stop)
    echo "$service を停止します…"
    # サービスを停止するコマンドをここに追加
    ;;
  restart)
    echo "$service を再起動します…"
    # サービスを再起動するコマンドをここに追加
    ;;
  *)
    echo "エラー: 無効な操作です。使用できる操作は start, stop, restart です。"
    exit 1
    ;;
esac

echo "処理が完了しました。"

説明

  1. サービス名のチェック
    『if』文を使用して、サービス名が入力されているかを確認します。入力が空の場合はエラーメッセージを表示してスクリプトを終了します。
  2. 操作の選択と実行
    『case』文を使用して、ユーザーが選択した操作(start、stop、restart)に応じた処理を実行します。選択肢にない操作が入力された場合はエラーメッセージを表示します。
  3. 柔軟なエラーハンドリング
    条件分岐を組み合わせることで、エラーを効率的に処理し、スクリプトの安全性を向上させています。

 このスクリプトは、サービスの管理だけでなく、メニュー形式で複数の選択肢を提供する他の用途にも応用可能です。たとえば、ファイル操作やシステム情報の表示など、さまざまなタスクに拡張できます。条件分岐を組み合わせたスクリプトを活用することで、複雑な処理を効率的に実現できるようになります。この例をベースに、自分のニーズに合わせたスクリプトを作成してみましょう。

Shellスクリプトにおける条件分岐は、プログラムの動作を制御する重要な要素ですが、複雑なロジックをそのまま記述すると、コードが冗長になり、可読性や保守性が低下することがあります。本セクションでは、条件分岐を効率的に記述し、スクリプトの品質を向上させるためのテクニックをいくつか紹介します。

『if』文と『case』文を活用したディスク使用量のチェックスクリプト

ディスク使用量を監視し、使用量が一定の閾値を超えた場合に警告を出すスクリプトは、システム管理者にとって欠かせないツールです。

この例では、『if』文と『case』文を組み合わせて、簡潔で効果的なディスクチェックスクリプトを構築します。

#!/bin/bash

# ディスク使用量の取得
disk_usage=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')

# 条件分岐でディスク使用量をチェック
if [ $disk_usage -ge 90 ]; then
  echo "警告: ディスク使用量が90%を超えています!"
  case $disk_usage in
    9[0-9])
      echo "注意: ディスクがほぼ満杯です。すぐに空き容量を確保してください。"
      ;;
    100   )
      echo "重大: ディスクが完全に満杯です。緊急対応が必要です。"
      ;;
  esac
else
  echo "ディスク使用量は正常範囲内です (${disk_usage}%)。"
fi

 ネストした条件をシンプルにする方法

条件分岐が複雑になると、コードが読みにくく、メンテナンスが難しくなることがあります。

このセクションでは、ネストした条件をシンプルにするための方法を解説します。論理演算子や関数を活用することで、コードの可読性を向上させましょう。

!/bin/bash

read -p "数字を入力してください: " num

# ネストを避けた条件分岐
if [ $num -lt 10 ]; then
  echo "入力値は10未満です。"
elif [ $num -le 20 ]; then
  echo "入力値は10以上20以下です。"
else
  echo "入力値は20を超えています。"
fi

 条件分岐のよくある質問への回答

条件分岐に関して初心者が抱きやすい疑問やつまずきがちなポイントについて解説します。これらの質問とその回答を参考にすることで、スクリプト作成時の問題解決に役立てましょう。

『if』文と『case』文の違いは何ですか?どちらを使えば良いのでしょうか?

構文エラーの多くは、条件式内のスペース不足や演算子の誤用によるものです。たとえば、以下の例はエラーを引き起こします。

誤り

if [$value -eq 10]; then # スペース不足
  echo "値は10です。"
fi

正解

if [ $value -eq 10 ]; then # スペースを正しく配置
  echo "値は10です。"
fi


ネストが深い条件分岐を簡潔にする方法はありますか?

ネストが深い場合、論理演算子(&&や||)を使って条件を1行にまとめたり、共通処理を関数化する方法があります。

# 改善前
if [ $value -gt 10 ]; then
  if [ $value -lt 20 ]; then
    echo "値は10より大きく20未満です。"
  fi
fi

# 改善後
if [ $value -gt 10 ] && [ $value -lt 20 ]; then
  echo "値は10より大きく20未満です。"
fi


『if』文を使った条件分岐の最適化には何が必要ですか?

以下のポイントを押さえることで、条件分岐を最適化できます。

ポイント

  • 複雑な条件を簡潔に書き換える(論理演算子の活用)。
  • よく使う条件を関数に切り出して再利用する。
  • 必要に応じて『case』文を使用して、コードを見やすく整理する。

この記事を読んだら、次は 「【Shellの基礎知識】ループ処理の基本|効率化と応用例を解説」 を読むのがおすすめです!

よく読まれている記事

1

IT入門シリーズ 🟢 STEP 1: ITの基礎を知る(ITとは何か?)├─【IT入門】ITとは?仕組みや活用方法をわかりやすく解説├─【IT入門】インターネットとは?仕組み・使い方を ...

2

「私たちが日々利用しているスマートフォンやインターネット、そしてスーパーコンピュータやクラウドサービス――これらの多くがLinuxの力で動いていることをご存じですか?無料で使えるだけでなく、高い柔軟性 ...

3

Shellスクリプト基礎知識(全13記事+2) ├─【Shellの基礎知識】Shellスクリプト入門|初心者が押さえる基本├─【Shellの基礎知識】変数と特殊変数の使い方|初心者向け解説├─【She ...

-Shell の基礎知識
-, , , ,