Shellスクリプト

【Shellスクリプト】条件分岐「if」「case」について!

2020年4月4日

シェルでは制御構造コマンドとして、条件分岐文として「if」「case」が利用できます。シェルスクリプトを習得する上で非常に重要な制御文なので、この機会にマスターしましょう。

この記事でわかること

  • 条件分岐とは?
    • if文とは?
    • case文とは?

条件分岐とは?

条件分岐とは、「Aという条件を満たした場合に繰り返し処理を実行し、Bという条件になったら処理を辞める」といった条件式を指しています。中でも「if文」と「case文」は、よく用いられる条件分岐構文になります。

if文とは?

if文は実行結果「真(true)」「偽(false)」によって分岐する構文です。例えば、「文字列Aと文字列Bは一致しているか?」といった考え方です。「if」文は、ほとんどの場合「test」コマンドと組み合わせて用いられます。

また、多少処理的に複雑になりますが、「ネスト(入れ子)」構造にすることも可能です。

「if-elif-else」文

条件分岐を複数に分けたい場合は「if-elif-else」文で制御します。「elif」は、単純に条件の数分指定可能です。「それ以外(すべてに該当しない場合)」の条件分岐を指定するには「else」を用います。

if-elif-else

上記のイメージを元にした書式を下記に記述します。

コマンドの書式

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

実際に「if」文を実行してみます。ここでは、引数に指定した"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-else」文も「if」文も考え方は全く同じです。分岐するアクションの数が異なるだけです。

「if-else」文

単純に2者択一等の「真(true)」「偽(false)」比較の場合には、「if-else」文を使用します。

if-else

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

コマンドの書式

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

「if」

単に「真(true)」の時のみの判定も可能です。

if

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

コマンドの書式

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

case文とは?

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

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

  • 処理の終了には「;;」を記述すること。
  • 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分に対応した記述例)

[ <BASE_DIR>/case_pattern.sh ]

Case分に対応した実行例)

さらに詳しく

  • *(ワイルドカード)のみを条件とした場合は全ての文字列をマッチします。
    *は、すべての文字列にマッチします。
    abc*:「abc」で始まるすべての文字列にマッチします。
    a*bc :「a」ではじまり「bc」で終わる文字列すべてにマッチします。

  • [ - ]で設定した範囲の文字や数字にマッチします。
    具体的には下記のように範囲指定をしていします。
    [a - z]:変数の値が小文字のアルファベット「a~z」のときにマッチします。
    [A - Z]:変数の値が大文字のアルファベット「A~Z」のときにマッチします
    [a-zA-Z]は、変数の値がアルファベットの小文字と大文字のときにマッチします。
    [0 - 9]は、変数の値が数字の0~9のときにマッチします。

  • OR条件
    a || A):変数の値がaまたはAの時にマッチします。

|(パイプ)」は「or (または)」の意味で、パターンの一番最後には「何も合致しなかった場合」という意味で「 * ) 」とするのが一般的です。

*(アスタリスク)」は「すべてに合致する」という意味の特殊文字なので、上から順番にパターンを比較していき、すべてに合致しなかった場合、必ず一番最後の「*(アスタリスク)」でキャッチされ、処理を実行することになります。

よく読まれている記事

1

目次1 Shellとは?1.1 代表的なシェルの種類2 シェルスクリプトの違いとは? Shellとは? Shellとは、人間の理解できる言葉を機会へ伝えるプログラムです。 Linux環境でコマンドプロ ...

2

Linuxは主にサーバー用として利用されるOSです。大規模な基幹システムの開発者、ロボットや家電開発等の組み込み系エンジニア、ネットワーク機器やデータベースに携わるインフラエンジニアは触れることが多い ...

3

プログラミング言語を習得しようと思った時、必ずと言っていいほど候補として挙げられるのが「Java」というプログラミング言語です。 「Java」は、現在日本で最も使われている言語であり、非常に人気のある ...

4

この記事は、Linuxについて勉強している初心者の方向けに「Shellスクリプト」について解説します。最後まで読んで頂けましたら、Shellスクリプトはどのような役割を担っているのか?を理解出来るよう ...

-Shellスクリプト

Copyright© Beエンジニア , 2020 All Rights Reserved.