👏

シェルスクリプトの基礎⑤~if文のtestコマンド~

2021/01/11に公開

はじめに

くーばねてすをやっつけるためにLinuxさんと仲良くさせていただいているが、Linuxさんにはシェルのコマンドを格納しておくシェルスクリプトというファイルがあるらしいのでそれをまとめてみた。

概要

シェルスクリプトのif文の
■testコマンドと演算子
・文字列の比較で使われる演算子
・ 整数の比較
・ファイル属性評価演算子
・演算子を結合する
・&&と||でスマートにワンライナー条件指定
・エラー時に他のシェルスクリプトにエラー処理を引き継がせる
・エラー時に他のシェルスクリプトにエラー処理を引き継がせる~終了ステータスを指定する~

をまとめてみた^^

■testコマンドと演算子

前回やった条件式の指定を[]コマンドで囲ったが、testコマンドでも同じような結果が得られる。

testコマンドでの条件指定
if test 条件;then   

前回は[]で囲ったが、

suidou→OK
$ cat if_suidou.sh
#! /bin/bash
if [ "$1"="suidou" ];then     
	echo "OK"
else
	echo "NG"
fi              (フィ!!!)

↑と↓は同じ意味

suidou→OK
$ cat if_suidou.sh
#! /bin/bash
if test "$1"="suidou";then     
	echo "OK"
else
	echo "NG"
fi              (フィ!!!)

$ ./if_suidou.sh  suidou
OK               (できた!)

testコマンドだが、[]の方が読みやすいので[]が多く使われる。
[]もtestコマンドもまとめてtestコマンドという。

文字列の比較で使われる演算子

|演算子|内容|
| --- | --- | --- |
|文字列1 = 文字列2|文字列1と文字列2は等しい|
|文字列1 != 文字列2|文字列1と文字列2は等しくない|
|-n 文字列1|文字列1は空文字列ではない|
|-z 文字列1|文字列1は空文字列である|
※空文字列とは文字が0文字であることをいう。

変数値の値が空文字列であればデフォルト値を設定せよ
#! /bin/bash
filename=$1
if [-z "$filename" ];then           (文字列が空文字列なら)
	filename="default.dat"      (デフォルト値をセット )
fi

整数の比較

整数値の比較演算子
|演算子|内容|
| --- | --- | --- |
|整数1 -eq 整数2|整数1と整数2が等しい|
|整数1 -ne 整数2|整数1と整数2が等しくない|
|整数1 -lt 整数2|整数1が整数2より小さい|
|整数1 -le 整数2|整数1が整数2以下|
|整数1 -gt 整数2|整数1が整数2より小さい|
|整数1 -ge 整数2|整数1が整数2以上|
※覚えられるかっ(@_@)
整数しか適用できないので小数点とか入っちゃうとダメみたい。

大きい整数のほうの引数を変数maxに代入するシェルスクリプト
#! /bin/bash
number1=$1
number2=$2
max=$number1

if [ "$number1" -lt "$number2" ];then ($number1が$number2より小さければ)
	max=$number2          (maxにnumber2を代入せよ)
fi

なんだか$を設定しゃいけないとことOKなとこがあるから気を付けよう('_')

ファイル属性評価演算子

|演算子|内容|
| --- | --- | --- |
|-e file|fileが存在する|
|-d file|fileがディレクトリである|
|-h file|fileがシンボリックリンクである|
|-L file|fileがシンボリックリンクである|
|-f file|fileが通常のファイルである|
|-r file|fileが読み込み権限がある|
|-w file|fileが書き込み権限がある|
|-x file|fileが実行権限がある|
|file1 -nt file2|fileが1file2より新しい|
|file1 -ot file2|file1がfile2より古い|
※覚えられるかっ(@_@)
ちなみにtestコマンドの[]の中に!を入れて[ ! 条件]とすると否定の意味になるそうだ。
この条件でない時に~せよと指定できるらしい。

入力したファイルがシンボリックリンクか結果を表示せよ
#! /bin/bash
symbolic_link=$1
if [ -h "$symbolic_link" ];then
	echo "シンボリックリンクです"
else
	echo "[ERROR]シンボリックリンクではありません"
fi

面白ーい(>_<)!

演算子を結合する

演算子は複数結合することができる。結合するための演算子を結合演算子という。
えぇ~(>_<)おれがおまえでおまえがおれみたいな!
|演算子|内容|
| --- | --- | --- |
|条件式1 -a 条件式2|条件式1と条件式2が両方とも真(AND)|
|式1 -o 条件式2|条件式1か条件式2いずれかが真(OR)|
|! 条件式|条件式1の条件でない時|
|(条件式)|条件式をグループ化する|
AND条件指定

パスがディレクトリであり、読み込み権限がある場合は
#! /bin/bash
dir=$1
if [-d "$dir" -a -r "$dir"];then      (←ANDで指定)
	echo "読み込み可能ディレクトリです"
else
	echo "[ERROR]"
fi

演算子が増えるとややこしいから気を付けよう('_')
結合演算子だけは覚えやすいので覚えておこう!
条件指定をグループ化
結合演算子は実は優先順位があったりするのでたくさんの演算子がある時はグループ化してしまう。
()はbashではメタ文字なのでグループは

\(条件\)

と囲う。

条件:ディレクトリであり、/homeか/etcのディレクトリであること
if [ -d "$dir" -a \("$dir" = "/home" -o "$dir" = "/etc "\) ];then    略

ややこしや~('_')とりあえず2個以上結合演算子がある時はグループ化しておいたほうがよさそう。

&&と||でスマートにワンライナー条件指定

わざわざif文を記述しなくてもワンライナーで条件表記できることもある。

条件が真であれば処理をする
$ [条件] && 処理
$ [条件] || 処理
ファイルが存在すればコマンド実行
$ [ -f file.txt ] && cat file.txt
ファイルが存在しなければコマンド実行
$ [ -f file.txt ] || touch file.txt

えぇ(>_<)めっちゃスマート!
この記述はif文のなかでも使えることができる。

3より大きくて6より小さい場合は処理せよ
#! /bin/bash
score=$1
if [ "$score" -gt 3 ] && [ "$score" -lt 6 ];then
	echo "OK"
fi

↓こいつでもOKだけど

if [ "$score" -gt 3 -a "$score" -lt 6 ];then

エラー時に他のシェルスクリプトにエラー処理を引き継がせる~終了ステータスを指定する~

例えば指定した条件が該当しなかった場合などに他のシェルスクリプトにエラー処理を引き継がせるときはどのようにエラーと認識させればいいのだろうか。
シェルスクリプトでは特に指定されていない場合は最後のコマンドが終了ステータスの対象となる。

#! /bin/bash
date
ls
ls-a    (←ここが最終ステータス)

でも途中でエラーになってそこからエラーメッセージをだして他のシェルスクリプトにエラー処理をさせたい場合、
途中コマンドの次に

exit 終了ステータス

と記述する。
終了ステータスが指定されていない時は、直前のコマンドが終了ステータスの対象になる。

まとめ

眠い!(>_<)

Discussion