Linux講座にようこそ。このページは「Linuxの使い方 - 第6章 シェルスクリプトの作り方」です。

Linuxの使い方

6. シェルスクリプトの作り方(5/8)

6.7 制御演算(1/2)

ここでの制御演算とは条件判定や繰り返し制御を意味します。条件判定は指定した条件の成立(真)や、不成立(偽)により処理を振り分けます。また、繰り返しは指定した条件が成立(真)している間や、不成立(偽)の間、特定の処理を繰り返し実行します。

ここで説明する内容は次のものです。

6.7.1 比較演算子

条件の記述形式は数値の比較の場合は(( 式 ))で、文字列の比較とファイル演算子の場合は[[ 式 ]]になり型式が異ります。また、(( 式 ))の場合は「式」の前後に空白があってもなくても構いませんが、[[ 式 ]]の場合は「式」の前後に空白が1個以上必要ですので注意してください。

「式」には変数や下表に示す比較演算子を使って、条件判定のための条件や、繰り返し制御のための条件を記述します。

【表6-12】数値の比較演算子一覧
演算子意味
数値1 > 数値2数値1は数値2より大きい。
数値1 < 数値2数値1は数値2より小さい。
数値1 >= 数値2数値1は数値2以上。(等しいか大きい)
数値1 <= 数値2数値1は数値2以下。(等しいか小さい)
数値1 == 数値2数値1と数値2は等しい。
数値1 != 数値2数値1と数値2は異なる。
【表6-13】文字列の比較演算子一覧
演算子意味
文字列1 > 文字列2文字列1は文字列2より辞書順で後ろにある。(大きい)
文字列1 < 文字列2文字列1は文字列2より辞書順で前にある。(小さい)
文字列1 = 文字列2文字列1と文字列2は等しい。(==でも可)
文字列1 != 文字列2文字列1と文字列2は異なる。
-n 文字列文字列が空ではない。
-z 文字列文字列が空である。
【表6-14】ファイル演算子一覧
ファイル演算子意味
-d ファイルファイルが存在しかつ、ディレクトリである。
-e ファイルファイルが存在する。(ディレクトリもファイルとして認識する)
-f ファイルファイルが存在しかつ、通常ファイルである。
-r ファイル読み込み(read)保護モードが設定されている。
-w ファイル書き出し(write)保護モードが設定されている。
-x ファイル実行(excute)保護モードが設定されている。
-s ファイルファイルが存在し、かつ空ではない。
ファイル1 -nt ファイル2ファイル1がファイル2よりも新しい。
ファイル1 -ot ファイル2ファイル1がファイル2よりも古い。

複数の条件を指定したい場合は論理演算子を使用します。条件としては上記演算子を使用した式や変数を指定できます。

【表6-15】論理演算子一覧
論理演算子意味
条件1 && 条件2全ての条件が真のとき真になる。(論理積、AND)
条件1 || 条件2条件が真のものが1つ以上あれば真になる。(論理和、OR)
! 条件真・偽を反転する。(論理否定、NOT)

6.7.2 ifコマンド

ifコマンドは条件判定のコマンドで、条件が成立(真)不成立(偽)により処理を振り分けます。

形式

ifコマンドには2つの形式が有ります。条件が2つの場合(真か偽か)は形式1を使い、複数のときは形式2を使います。また、条件不成立時に実行するコマンドが無い場合はelse以下を省略できます。(fiは必要です)

※ 形式1
if 条件
then ← ifとthenを1行で記述するときは;(セミコロン)で区切ります(if 条件 ; then)
  コマンドリスト ← 条件成立時に実行するコマンドを指定します
else
  コマンドリスト ← 条件不成立時に実行するコマンドを指定します
fi ← ifコマンドの最後を表します

※ 形式2
if 条件
then
  コマンドリスト
elif 条件 ← else ifの意味です。elifに対するfiはありません
then
  コマンドリスト
elif 条件 ← else ifは複数の指定ができます
then
  コマンドリスト
else
  コマンドリスト ← else if条件不成立時に実行するコマンドを指定します
fi

例題

例題1

引数あるいは、キーボードから入力されたディレクトリの下のファイルやディレクトリの数を表示します。(ex50.sh)

#!/bin/bash
# 機能  :  指定されたディレクトリの下のファイルやディレクトリの数を表示します
# 作成  :  メリー
 
if [[ -z "$1" ]]           # 第1引数の有無をチェック
then
    read -p "ディレクトリのパス名を入力して下さい --> " dir
else
    dir="$1"
fi
 
if [[ ! -d "$dir" ]]
then
    echo "${dir}は存在しないかまたは、ディレクトリではありません"
    exit 1               # 終了ステータス1で終了
fi
 
kazu=$(ls "$dir" | wc -l)  # wcコマンドで行数を求める
 
echo "${dir}には${kazu}個のファイルやディレクトリがあります"

if [[ ! -d "$dir" ]]の!は真・偽を反転しますので、「ディレクトリでない」という条件になります。

$ ex50.sh ../KANRI
../KANRIには6個のファイルやディレクトリがあります
$ echo $? ← 終了ステータスを表示します
0
$
$ ex50.sh
ディレクトリのパス名を入力して下さい --> ../KANRI
../KANRIには4個のファイルやディレクトリがあります
$
$ ex50.sh
ディレクトリのパス名を入力して下さい --> ../DUMMY
../DUMMYは存在しないかまたは、ディレクトリではありません
$ echo $?
1 ← ex50.shがエラー終了したので、終了ステータスは1です
$
$ ex50.sh ../DUMMY
../DUMMYは存在しないかまたは、ディレクトリではありません
$
例題2

メニューにより四則演算を行います。メニュー番号により四則演算の種類を指定します。(ex51.sh)

#!/bin/bash
# 機能  :  四則演算を行います
# 作成  :  メリー
 
echo -e "(1)加算\n(2)減算\n(3)乗算\n(4)除算"
read -p "番号を入力して下さい --> " bango
 
if [[ -n "$bango" ]]
then
    read -p "数値を2つ入力して下さい --> " atai1 atai2
    if [[ -n "$atai1" ]] && [[ -n "$atai2" ]]
    then
        if (( "$bango" == 1 ))         # 加算
        then
             echo "${atai1} + ${atai2} = " $(( $atai1 + $atai2 ))
        elif (( "$bango" == 2 ))       # 減算
        then
             echo "${atai1} - ${atai2} = " $(( $atai1 - $atai2 ))
        elif (( "$bango" == 3 ))       # 乗算
        then
             echo "${atai1} * ${atai2} = " $(( $atai1 * $atai2 ))
        elif (( "$bango" == 4 ))       # 除算
        then
            echo "${atai1} / ${atai2} = " $(( $atai1 / $atai2 ))
        else                           # それ以外
            echo "番号が不当です"
        fi
    else
        echo "数値が入力されませんでした"
    fi
else
    echo "番号が入力されませんでした"
fi
$ ex51.sh
(1)加算
(2)減算
(3)乗算
(4)除算
番号を入力して下さい --> 1
数値を2つ入力して下さい --> 10 20
10 + 20 =  30
$
$ ex51.sh
(1)加算
(2)減算
(3)乗算
(4)除算
番号を入力して下さい --> 5
数値を2つ入力して下さい --> 10 20
番号が不当です
$
$ ex51.sh
(1)加算
(2)減算
(3)乗算
(4)除算
番号を入力して下さい --> 2
数値を2つ入力して下さい --> 10
数値が入力されませんでした
$

6.7.3 caseコマンド

caseコマンドは複数の条件により処理を振り分けます。ifコマンドと似ていますが、条件が多いときにはifコマンドより処理を分りやすく記述できます。

形式

「式」の値と一致するパターンの所のコマンドを実行します。コマンドリストの最後にはセミコロンを2個指定します。パターンにはワイルドカード(*、?、[ ]、等)が指定できますし、複数のパターンを|(縦線)で区切って指定できます。

case 式 in ← 式には変数や位置パラメータを指定できます
  パターン1)
    コマンドリスト;; ← コマンドリストの最後は;;(セミコロン2個)です
  パターン2)
    コマンドリスト;;

  ・・・

  パターンn)
    コマンドリスト;;
esac ← caseコマンドの最後を表します

複数のパターンを指定した例を示します。変数nameの値がMまたはmの場合は「Merry」を、Kまたはkの場合は「Ken」を、それ以外の場合は「?」を表示します。

case "$name" in
    "M" | "m" ) echo "Merry";;
    "K" | "k" ) echo "Ken";;
    * ) echo "?";;
esac

例題

四則演算を行います。メニューに表示された記号により四則演算の種類を指定します。(ex52.sh)

#!/bin/bash
# 機能  :  四則演算を行います
# 作成  :  メリー
 
echo -e "(+)加算\n(-)減算\n(*)乗算\n(/)除算"
read -p "演算子を入力して下さい --> " enzansi
 
if [[ -n "$enzansi" ]]
then
    read -p "数値を2つ入力して下さい --> " atai1 atai2
    if [[ -n "$atai1" ]] && [[ -n "$atai2" ]]
    then
        case "$enzansi" in                  # 変数enzansiの値により処理を振り分ける
            '+' ) echo "${atai1} + ${atai2} = " $(( $atai1 + $atai2 ));;
            '-' ) echo "${atai1} - ${atai2} = " $(( $atai1 - $atai2 ));;
            '*' ) echo "${atai1} * ${atai2} = " $(( $atai1 * $atai2 ));;
            '/' ) echo "${atai1} / ${atai2} = " $(( $atai1 / $atai2 ));;
            * ) echo "演算子が不当です";;    # *は上記パターン以外の全てに一致
        esac
    else
        echo "数値が入力されませんでした"
    fi
else
    echo "演算子が入力されませんでした"
fi
$ ex52.sh
(+)加算
(-)減算
(*)乗算
(/)除算
演算子を入力して下さい --> +
数値を2つ入力して下さい --> 100 200
100 + 200 =  300
$ ex52.sh
(+)加算
(-)減算
(*)乗算
(/)除算
演算子を入力して下さい --> *
数値を2つ入力して下さい --> 100 3
100 * 3 =  300
$ ex52.sh
(+)加算
(-)減算
(*)乗算
(/)除算
演算子を入力して下さい --> @
数値を2つ入力して下さい --> 100 200
演算子が不当です
$