testコマンドと戻り値

if文やwhileループなど、さまざまな場面で使う「test」文ですが、真(0)や偽(1)を判断する為にさまざまな比較をする事ができます。

まずは前回までに度々使用した文字列比較。
ポイントは「"(ダブルクォーテーション)」で括る事でした。

以下の様な感じでしたね。

test "string" = "string"

変数に格納されている文字列を比較する時は、こんな感じでした。

test "${V_STR}" = "string"

比較式の左辺と右辺を比較し、同じであれば真(0)と判定し、違っていれば偽(1)と判定します。

文字列の判定は、上記の様な2つの文字列の比較以外にも以下の様なオプションが使えます。

"STRING1" = "STRING2"     文字列「STRING1」と文字列「STRING2」が同じならば真
"STRING1" != "STRING2"    文字列「STRING1」と文字列「STRING2」が同じでないならば真
-z "STRING"                      文字列「STRING」の長さが0であれば真
-n "STRING"                      文字列「STRING」の長さが0より大きければ真
"STRING"                          文字列「STRING」がnullでなければ真

次に使う頻度が高いのは数値比較です。
while文の説明時に軽く使用しましたが、数値比較も文字列と同じ様に左辺と右辺の比較をする形で行います。

INT1 -eq INT2        数値「INT1」と数値「INT2」が同じであれば真
INT1 -ne INT2        数値「INT1」と数値「INT2」が同じでなければ真
INT1 -lt INT2        数値「INT1」が数値「INT2」より小さければ真
INT1 -le INT2        数値「INT1」が数値「INT2」以下であれば真
INT1 -gt INT2        数値「INT1」が数値「INT2」より大きければ真
INT1 -ge INT2        数値「INT1」が数値「INT2」以上であれば真

ファイルの属性等の判定もできます。

-a FILE            FILE が存在すれば真。
-b FILE            FILE が存在し、かつブロック特殊ファイルならば真。
-c FILE            FILE が存在し、かつキャラクタ特殊ファイルならば真。
-d FILE            FILE が存在し、かつディレクトリならば真。
-e FILE            FILE が存在すれば真。
-f FILE            FILE が存在し、かつ通常ファイルならば真。
-g FILE            FILE が存在し、かつ set-group-id されていれば真。
-h FILE            FILE が存在し、かつシンボリックリンクならば真。
-k FILE            FILE が存在し、かつ ‘‘sticky’’ ビットが設定されていれば真。
-p FILE            FILE が存在し、かつ名前付きパイプ (FIFO) ならば真。
-r FILE            FILE が存在し、かつ読み込み可能ならば真。
-s FILE            FILE が存在し、かつそのサイズが 0 より大きければ真。
-t fd            ファイル・ディスクリプター fd がオープンされており、かつ端末を参照していれば真。
-u FILE            FILE が存在し、かつ set-user-id ビットが設定されていれば真。
-w FILE            FILE が存在し、かつ書き込み可能ならば真。
-x FILE            FILE が存在し、かつ実行可能ならば真。
-O FILE            FILE が存在し、かつ (実行中のシェルの) 実効ユーザ ID に所有されていれば真。
-G FILE            FILE が存在し、かつ (実行中のシェルの) 実効グループ ID に所有されていれば真。
-L FILE            FILE が存在し、かつシンボリックリンクならば真。
-S FILE            FILE が存在し、かつソケットならば真。
-N FILE            FILE が存在し、かつ前回読み込まれた後に修正されていれば真。
FILE1 -nt FILE2        FILE1 が (変更日時に関して) FILE2 より新しければ真。
FILE1 -ot FILE2        FILE1 が FILE2 より古ければ真。
FILE1 -ef FILE2        FILE1 と FILE2 とでデバイス番号と i-ノード番号が同じならば真。

その他にも以下の様なオプションがあります。
※個人的には使用は推奨しません。

! JUDGE            判定文「JUDGE」が偽であれば真
JUDGE1 -a JUDGE2    判定文「JUDGE1」が真であり、かつ判定文「JUDGE2」が真であれば真
JUDGE1 -o JUDGE2    判定文「JUDGE1」もしくは、判定文「JUDGE2」が真であれば真

if文(条件文)では、この判定結果を見て、真の場合はthenの後ろに書かれた処理内容を実行し、偽の場合はelseの後ろに書かれた処理内容を実行します。
ですが、この判定結果の真(0)と偽(1)はどのようにして取り出すのでしょうか?

「test」コマンドに限らず、どのようなコマンドでもそうなのですが、コマンドを実行した際、コマンドが成功したのか失敗したのかを「戻り値」で出力しています。
出力していると言っても、画面にではなくコマンド処理結果は特殊変数「$?」に格納されています。
特殊変数と言っても、参照の仕方は他の変数と同じですので、以下の様に「echo」文で画面に出力する事もできます。

echo $?

if文はこの戻り値によって真偽を判断しています。
次はこの戻り値についてもう少し掘り下げて解説します。