この記事を読めばシェルスクリプトで開発時に必要なif文の基本構文と条件分岐オプションの書き方マスターすることができます。
シェルスクリプトでもif文(条件分岐文)を利用する時には、比較対象が文字列なのか?数値型なのか?を意識する必要があります。
またファイルやディレクトリが存在するか?ファイルの権限はどんな状態か?などシェルスクリプト独特の条件分岐も存在します。
この記事で習得できること
- シェルスクリプトの基本構文
- シェルスクリプトの文字列比較・数値比較のやり方
- オプションを利用した条件分岐
- 上記の条件を論理和・論理積・論理否定で使用する方法
if文の基本構文
まずはif文の基本構文を学びましょう。 シェルスクリプトも通常のプログラミング言語と同様に「if-then」で書きます。
if文
下が最も単純なif文です。「[] : square brackets」の間の条件に半角スペースを忘れないようにしましょう。
if [ <条件> ]; then
処理
fi
if-else文
次がif-else文です。条件以外ならばelse文の処理が実行されます。
if [ <条件> ]; then
ifが正の時の処理
else
ifが負の時の処理
fi
if-elseif-else文
次がif-elseif-else文です。elseif文はシェルスクリプトでは「elif」と書くので注意してください。
if [ <条件> ]; then
ifが正の時の処理
elif
elseifが正の時の処理
else
ifとelseifが負の時の処理
fi
文字列を比較する方法
↓が文字列を比較方法の一覧です。
オプション | 意味 |
---|---|
文字列A = 文字列B | 文字列Aと文字列Bが等しければ真 |
文字列A != 文字列B | 文字列Aと文字列Bが等しくなければ真 |
文字列 | 文字列の長さが0より大きければ真 |
-n 文字列 | |
-z 文字列 | 文字列の長さが0であれば真 |
↓がサンプルスクリプトになります。
# 文字列Aが文字列B等しい
if [ ${STR_A} = ${STR_B} ]; then
# 処理
fi
# 文字列Aと文字列Bが違う
if [ ${STR_A} != ${STR_B} ]; then
# 処理
fi
# 文字列の長さが0以上の時
if [ ${STR} ]; then
# 処理
fi
# 文字列の長さが0以上の時
if [ -n ${STR} ]; then
# 処理
fi
# 文字列の長さが0の時
if [ -z ${STR} ]; then
# 処理
fi
数値を比較する方法
数値を比較の一覧は↓になります。覚え方も載せておきますので暗記しましょう。
オプション | 意味 | 覚え方 |
---|---|---|
数値A -eq 数値B | 数値ABが等しければ真となる。 | equal => -eq |
数値A -ne 数値B | 数値ABが等しくなければ真となる。 | not equal => -ne |
数値A -lt 数値B | 数値A<数値Bならば真となる。 | less than => -lt |
数値A -le 数値B | 数値A ≦ 数値Bならば真となる。 | less than or equal => -le |
数値A -gt 数値B | 数値A > 数値Bならば真となる。 | greater than => -gt |
数値A -ge 数値B | 数値A ≧ 数値Bならば真となる。 | greater than or equal => -ge |
↓がサンプルスクリプトになります。
# 数値Aと数値Bが等しい
if [ ${NUM_A} -eq ${NUM_B} ]; then
# 処理
fi
# 数値Aと数値Bが違う
if [ ${NUM_A} -ne ${NUM_B} ]; then
# 処理
fi
# 数値Aが数値Bより小さい
if [ ${NUM_A} -lt ${NUM_B} ]; then
# 処理
fi
# 数値Aが数値B以下
if [ ${NUM_A} -le ${NUM_B} ]; then
# 処理
fi
# 数値Aが数値Bより大きい
if [ ${NUM_A} -gt ${NUM_B} ]; then
# 処理
fi
# 数値Aが数値B以上
if [ ${NUM_A} -ge ${NUM_B} ]; then
# 処理
fi
ファイル・ディレクトリの確認
ファイル・ディレクトリが存在するか?
権限の設定はどうなっているか?
を確認するかは、シェルスクリプトを書く上でマストで覚えるべき条件文になります。
↓がファイル・ディレクトリ確認関連のオプションになります。
オプション | 意味 |
---|---|
-e ファイル名 or ディレクトリ名 | ファイルが存在するならば真 |
-f ファイル名 | ファイルが普通のファイルならば真 |
-s ファイル名 | ファイルが 0 より大きいサイズならば真 |
-L シンボリックリンク | ファイルがシンボリックリンクならば真 |
-ef シンボリックリンク | ファイルがハードリンクならば真 |
-d ディレクトリ名 | ディレクトリ名がディレクトリならば真 |
-r ファイル or ディレクトリ名 | ファイルやディレクトリが読み取り可能ならば真 |
-w ファイル or ディレクトリ名 | ファイルやディレクトリが書き込み可能ならば真 |
-x ファイル or ディレクトリ名 | ファイルやディレクトリが実行可能ならば真 |
-O ファイル or ディレクトリ名 | ファイルやディレクトリが実行ユーザの所有者ならば真 |
-G ファイル or ディレクトリ名 | ファイルやディレクトリが実行ユーザのグループならば真 |
ファイルA -ot ファイルB | ファイルAがファイルBよりファイル更新が古ければ真 |
ファイルA -nt ファイルB | ファイルAがファイルBよりファイル更新が新しければ真 |
※**これらのオプションは「test」コマンドが省略されていることも頭の片隅に入れておいてください。
**↓がサンプルスクリプトです。
# ファイルが存在する時
if [ -e ${FILE} ]; then
# 処理
fi
# ファイルが通常ファイルの時
if [ -f ${FILE} ]; then
# 処理
fi
# ファイルサイズが0以上の時
if [ -f ${FILE} ]; then
# 処理
fi
# シンボリックリンクの時
if [ -L ${SLINK} ]; then
# 処理
fi
# ハードリックリンクの時
if [ -df ${LINK} ]; then
# 処理
fi
# ディレクトリの時
if [ -f ${DIR} ]; then
# 処理
fi
# ファイルが読み取り可能の時
if [ -r ${FILE} ]; then
# 処理
fi
# ファイルが書き込み可能の時
if [ -w ${FILE} ]; then
# 処理
fi
# ファイルが実行可能の時
if [ -x ${FILE} ]; then
# 処理
fi
# ファイルが実行ユーザの所有者の時
if [ -O ${FILE} ]; then
# 処理
fi
# ファイルが実行ユーザのグループの時
if [ -G ${FILE} ]; then
# 処理
fi
# ファイルAがファイルBよりファイル更新が古い時
if [ ${FILE_A} -ot ${FILE_B} ]; then
# 処理
fi
# ファイルAがファイルBよりファイル更新が新しい時
if [ ${FILE_A} -nt ${FILE_B} ]; then
# 処理
fi
複数の条件(OR・AND・NOT)を利用
前述で紹介した条件を、複数の条件で利用する方法を紹介します。
オプション | 意味 |
---|---|
条件A -o 条件B | 条件Aまたは条件Bの場合は真 |
条件A || 条件B | |
条件A -a 条件B | 条件Aかつ条件Bの場合は真 |
条件A && 条件B | |
! 条件 | 条件が偽の時は真 |
OR条件(論理和)とAND条件(論理積)は2つ利用できますが、
「||」や「&&」を利用するとシェルスクリプトを使ったことがない人にも分かりやすくなります。
また一般的なプログラミング同様に、論理積と論理和が複合される演算では論理和から処理がされる点に注意しましょう。
↓がサンプルスクリプトになります。
# 「数値Aと数値Bが等しい」 または 「数値Cと数値Dが等しい」
if [ ${NUM_A} -eq ${NUM_B} -o ${NUM_C} -eq ${NUM_D} ]; then
# 処理
fi
if [ ${NUM_A} -eq ${NUM_B} || ${NUM_C} -eq ${NUM_D} ]; then
# 処理
fi
# 「数値Aと数値Bが等しい」 かつ 「数値Cと数値Dが等しい」
if [ ${NUM_A} -eq ${NUM_B} -a ${NUM_C} -eq ${NUM_D} ]; then
# 処理
fi
if [ ${NUM_A} -eq ${NUM_B} &&-eq ${NUM_D} ]; then
# 処理
fi
# ファイルが存在しない時
if [ ! -e ${FILE} ]; then
# 処理
fi
おまけ:その他覚えておくこと
その他私が知らなかったものがあったので備忘録のため載せておきます。
※「help test」コマンドで利用できるオプションを確認することができます。
オプション | 意味 |
---|---|
-b ファイル名 | ファイルがブロック型デバイスならば真 |
-c ファイル名 | ファイルがキャラクタ型デバイスならば真 |
-u ファイル名 | ファイルにuidビットが立っていたら真 |
-g ファイル名 | ファイルにgidビットが立っていたら真 |
-k ファイル名 | ファイルにstickyビットが立っていたら真 |
-S ファイル名 | ファイルがソケットならば真 |
-p ファイル名 | ファイルが名前付きパイプ(FIFO)ならば真 |
-t num | ファイルディスクリプタnumが端末ならば真 |
-t 0 | 標準入力が端末であれば真 |
-t 1 | 標準出力が端末であれば真 |
-t 2 | 標準エラー出力が端末であれば真 |