5.2.2 条件式

条件式では,数値比較,文字列比較,ファイル属性,論理演算子および三項演算子を使用します。条件式の共通仕様を説明します。

letコマンドの引数にtestコマンドの引数(-eqなど)を指定した場合,letコマンドは変数と解釈して動作します。

[[]]を使用して条件判定するときの使用例を次に示します。

[[]]で条件判定するときの使用例

if [[ $arg1 -eq $args ]]; then
   echo TRUE
fi

<この項の構成>
(1) 数値比較
(2) 文字列比較
(3) ファイル属性
(4) 論理演算
(5) 三項演算子

(1) 数値比較

数値の比較に使用する演算子を次の表に示します。

表5-21 数値の比較に使用する演算子

演算子を用いた条件式判定testコマンドまたは[[]]での使用可否letコマンドまたは(())での使用可否
数値1 -eq 数値2数値1と数値2が等しい場合は真。×
数値1 -ne 数値2数値1と数値2が等しくない場合は真。×
数値1 -ge 数値2数値1が数値2以上の場合は真。×
数値1 -gt 数値2数値1が数値2より大きい場合は真。×
数値1 -le 数値2数値1が数値2以下の場合は真。×
数値1 -lt 数値2数値1が数値2より小さい場合は真。×
数値1 == 数値2数値1と数値2が等しい場合は真。※1
数値1 != 数値2数値1と数値2が等しくない場合は真。※1
数値1 >= 数値2数値1が数値2以上の場合は真。×
数値1 > 数値2数値1が数値2より大きい場合は真。※1※2
数値1 < 数値2数値1が数値2より小さい場合は真。※1※2
数値1 <= 数値2数値1が数値2以下の場合は真。×
(凡例)
○:使用できます。
×:使用できません。
注※1
数値ではなく,文字列として比較します。文字列比較については,「5.2.2(2) 文字列比較」を参照してください。
注※2
[[ ]]で使用できます。testコマンドでは使用できません。

数値比較の使用例を次に示します。

a=1
b=2
if [[ $a -lt $b ]]; then
 echo TRUE
else
 echo FALSE
fi

while (( $a != $b )); do
 echo LOOP
 ((a+=1))
done

(2) 文字列比較

文字列の比較に使用する演算子を次の表に示します。

表5-22 文字列の比較に使用する演算子

演算子を用いた条件式判定testコマンドまたは[[]]での使用可否letコマンドまたは(())での使用可否
-n 文字列文字列の長さが1文字以上の場合は真。×
-z 文字列文字列の長さが0の場合は真。×
-o 文字列文字列が現在有効に設定されているシェルオプションの文字列と一致する場合は真。シェルオプションの文字列については,「表5-34 setコマンドで設定するシェルオプション」の「名称」を参照してください。×
文字列 = pattern文字列とpatternが一致する場合は真。×
文字列 == pattern文字列とpatternが一致する場合は真。×
文字列 != pattern文字列とpatternが不一致の場合は真。×
文字列1 < 文字列2文字列1と文字列2をASCIIコード順に比較します。文字列1より文字列2が大きい場合は真。×
文字列1 > 文字列2文字列1と文字列2をASCIIコード順に比較します。文字列1より文字列2が小さい場合は真。×
(凡例)
○:使用できます。
×:使用できません。
注※
[[ ]]で使用できます。testコマンドでは使用できません。

比較する文字列にはスペースなどが含まれる場合があるため,"(ダブルクォーテーション)で囲むことを推奨します。使用例を次に示します。

str1="aaa"
str2="bbb"
test "$str1" == "$str2"
[[ "$str1" == "$str2" ]]

比較する文字列には*,?,[…]のワイルドカードが指定できます。ただし,testコマンドではワイルドカードを使用できません。また,ワイルドカードを使用した文字列を"(ダブルクォーテーション)で囲んだ場合,ワイルドカードが持つ意味が無効化されてしまうため,注意してください。使用例を次に示します。

str1="adsh"
str2="ads?"
str3="ad*"
[[ "$str1" == "$str2" ]]   ←ワイルドカードが無効。文字列"ads?"の比較をする
[[ $str1 != $str3 ]]       ←ワイルドカードが有効

[[ ]]による文字列比較の使用例を次に示します。ワイルドカードは,*,?,[…]が指定できます。

if [[ abc == ab* ]]; then
   echo TRUE
fi

ワイルドカードについては,「5.1.5(5) ワイルドカード」を参照してください。

(3) ファイル属性

ファイルの形式や権限などの属性を評価する場合に使用する演算子を次の表に示します。

表5-23 ファイルの形式や権限などの属性を評価する演算子

演算子を用いた条件式判定testコマンドまたは[[]]での使用可否letコマンドまたは(())での使用可否
-a filefileが存在する場合は真。×
-b filefileが存在し,ブロック型デバイスの場合は真。※1×
-c filefileが存在し,キャラクタ型デバイスの場合は真。※1×
-d filefileが存在し,ディレクトリの場合は真。×
-e filefileが存在する場合は真。×
-f filefileが存在し,レギュラーファイルの場合は真。×
-g filefileが存在し,setgidビットがセットされている場合は真。※1×
-h filefileが存在し,シンボリックリンクの場合は真。※2×
-k filefileが存在し,スティッキービットがセットされている場合は真。※1×
-p filefileが存在し,パイプファイルの場合は真。※1×
-r fileWindowsの場合,fileが存在する場合は真。
UNIXの場合,fileが存在し,カレントプロセスから読み込み可能なときは真。
×
-s filefileが存在し,ファイルサイズが1以上の場合は真。×
-t fd端末をオープンしているfdの場合は真。※3×
-u filefileが存在し,setuidビットがセットされている場合は真。※1×
-w fileWindowsの場合,読み取り専用属性が設定されていないか,またはディレクトリのときは真。
UNIXの場合,fileが存在し,カレントプロセスから書き込み可能なときは真。
×
-x fileWindowsの場合,次のどれかに該当するときは真。
  • 拡張子が「.com」,「.exe」,「.cmd」または「.bat」である
  • ディレクトリである
  • 環境ファイルのCHILDJOB_SHEBANGパラメーター(Windows,Linux限定)で設定した条件に一致するファイルである※4
UNIXの場合,fileが存在し,カレントプロセスから実行可能なときは真。
×
-G filefileが存在し,fileが属するグループが呼び出し元のプロセスの実効グループIDと一致している場合は真。※2×
-L filefileが存在し,シンボリックリンクの場合は真。※2×
-O filefileが存在し,所有者がプロセスの有効ユーザーIDの場合は真。※2×
-S filefileが存在し,ソケットの場合は真。※1×
file1 -ef file2file1とfile2が存在し,file1とfile2の実体が同じ(シンボリックリンク先が同じまたはハードリンク先が同じ)場合は真。※2×
file1 -nt file2file1とfile2が存在し,file1の更新日付がfile2よりも新しい場合は真。×
file1 -ot file2file1とfile2が存在し,file1の更新日付がfile2よりも古い場合は真。×
-H file常に偽。×
(凡例)
○:使用できます。
×:使用できません。
注※1
Windows環境の場合,存在しないファイル種別やフラグについて判定されるため,常に偽となります。
注※2
Windows環境でtestコマンドを実行する場合,判定時の処理がサポートされていないため,エラーとなります。ただし,UNSUPPORT_TESTパラメーターを指定することで,メッセージを出力してエラーとしたり,正常にしたりすることもできます。パラメーターの詳細については,「7.3 環境設定パラメーター」の「UNSUPPORT_TESTパラメーター(サポートしていない条件式の実行時の動作を定義する)【Windows限定】」を参照してください。
注※3
fdに10以上の値を指定しないでください。指定した場合,値は保証できません。
注※4
CHILDJOB_SHEBANGパラメーターの詳細については,「7.3 環境設定パラメーター」の「CHILDJOB_SHEBANGパラメーター(子孫ジョブとして実行するジョブ定義スクリプトファイルの実行プログラムパスを定義する)【Windows,Linux限定】」を参照してください。

ファイル属性の使用例を次に示します。

FILE="$HOME/script/test.ash"
if [[ -a $FILE ]];
then
 echo "$FILE exists."
else
 echo "$FILE does not exist."
fi

(4) 論理演算

論理演算で評価する場合に使用する演算子を次の表に示します。

表5-24 論理演算で評価する場合に使用する演算子

演算子を用いた条件式判定testコマンドまたは[[]]での使用可否letコマンドまたは(())での使用可否
expr1 -a expr2expr1とexpr2の結果が両方とも真の場合,真。×
expr1 -o expr2expr1とexpr2の結果がどちらか一方でも真の場合,真。×
expr1 && expr2expr1とexpr2の結果が両方とも真の場合,真。
expr1 || expr2expr1とexpr2の結果がどちらか一方でも真の場合,真。
! exprexprの結果が偽の場合,真。
(凡例)
○:使用できます。
×:使用できません。
注※
testコマンドで使用できます。[[ ]]は使用できません。

論理演算の使用例を次に示します。

DIR="/tmp"
FILE="/tmp/test.ash"
a=2
b=4
if test -d $DIR -a -a $FILE
then
 echo "$DIR is directory and $FILE exists."
else
 echo "$DIR is not directory or $FILE does not exist."
fi

while ((a*0 || b-3)); do
 echo LOOP
 let b-=1
done

ただし,testコマンドで論理演算子「&&」および「||」を使用する場合は,次のように記述してください。

a=1
b=2
c=3
if test "$a" == 1 && test "$b" == 2; then
   echo "True"
else
   echo "False"
fi
if test "$a" != "$b" || test "$a" != "$c"; then
   echo "True"
else
   echo "False"
fi

(5) 三項演算子

if-elseの省略記法である三項演算子を使用できます。JP1/Advanced Shellで使用できる三項演算子を次の表に示します。

表5-25 JP1/Advanced Shellで使用できる三項演算子

演算子を用いた条件式判定testコマンドまたは[[]]での使用可否letコマンドまたは(())での使用可否
expr1?expr2: expr3expr1の結果が真であればexpr2の結果,偽であればexpr3の結果を返します。×
(凡例)
○:使用できます。
×:使用できません。

三項演算子の使用例を次に示します。

VAR1=3
VAR2=2
ANSWER=0

((ANSWER=VAR1>VAR2?8+VAR1:8*VAR2))
echo $ANSWER