Yash マニュアル: test 組込みコマンド
Author: magicant
Description: Yash の test 組込みコマンドについて

# Test 組込みコマンド

Test 組込みコマンドは引数で指定した内容の判定を行います。

## 構文

- `test 判定式`
- `[ 判定式 ]`

Test コマンドはオプションとオペランドとを区別しません。コマンドライン引数は全て判定式として解釈します。コマンドが `[` の名前で実行された時は、判定式の後に `]` が必要です。

## 説明

Test コマンドは引数で与えられた判定式を評価し、結果が真ならば 0 の終了ステータスを、偽ならば 1 の終了ステータスで終了します。判定式は何種類かの演算子とそれに対する被演算子とからなります。

ファイルに関する判定を行う単項演算子は以下の通りです。指定したファイルがシンボリックリンクの場合、そのシンボリックリンクが指している先のファイルについて判定を行います (`-h`, `-L` 演算子を除く)。

`-b ファイル名`
  ファイルがブロックスペシャルファイルかどうか
`-c ファイル名`
  ファイルがキャラクタスペシャルファイルかどうか
`-d ファイル名`
  ファイルがディレクトリかどうか
`-e ファイル名`
  ファイルが存在するかどうか
`-f ファイル名`
  ファイルが通常のファイルかどうか
`-G ファイル名`
  ファイルのグループ ID がシェルの実効グループ ID に等しいかどうか
`-g ファイル名`
  ファイルの set-group-ID ビットが設定されているかどうか
`-h ファイル名`
`-L ファイル名`
  ファイルがシンボリックリンクかどうか
`-k ファイル名`
  ファイルの sticky ビットが設定されているかどうか
`-N ファイル名`
  ファイルの最終変更日時が最終アクセス日時より後かどうか
`-O ファイル名`
  ファイルのユーザ ID がシェルの実効ユーザ ID に等しいかどうか
`-p ファイル名`
  ファイルが FIFO (名前付きパイプ) かどうか
`-r ファイル名`
  ファイルが読み込み可能かどうか
`-S ファイル名`
  ファイルがソケットかどうか
`-s ファイル名`
  ファイルサイズが空でないかどうか
`-u ファイル名`
  ファイルの set-user-ID ビットが設定されているかどうか
`-w ファイル名`
  ファイルが書き込み可能かどうか
`-x ファイル名`
  ファイルが実行可能かどうか

ファイル記述子に関する判定を行う単項演算子は以下の通りです。

`-t ファイル記述子`
  ファイル記述子が端末かどうか (ファイル記述子は 0 以上の自然数で指定します)

文字列に関する判定を行う単項演算子は以下の通りです。

`-n 文字列`
  文字列が空文字列でないかどうか
`-z 文字列`
  文字列が空文字列かどうか

ファイルに関する判定を行う二項演算子は以下の通りです。

`ファイル名1 -nt ファイル名2`
  一つ目のファイルの更新時刻が二つ目のファイルより新しいかどうか (存在しないファイルは他のファイルより古いとみなす)
`ファイル名1 -ot ファイル名2`
  一つ目のファイルの更新時刻が二つ目のファイルより古いかどうか (存在しないファイルは他のファイルより古いとみなす)
`ファイル名1 -ef ファイル名2`
  二つのファイルが互いのハードリンクであるかどうか

文字列に関する判定を行う二項演算子は以下の通りです。

`文字列1 = 文字列2`
`文字列1 == 文字列2`
  二つの文字列が同じ文字列かどうか
`文字列1 != 文字列2`
  二つの文字列が異なる文字列かどうか
`文字列1 === 文字列2`
  二つの文字列が同じ文字列かどうか (現在のロケールに従った辞書式順序での比較)
`文字列1 !== 文字列2`
  二つの文字列が異なる文字列かどうか (現在のロケールに従った辞書式順序での比較)
`文字列1 < 文字列2`
  現在のロケールにおいて、一つ目の文字列が二つ目の文字列より辞書式順序で手前に来るかどうか。
`文字列1 <= 文字列2`
  現在のロケールにおいて、一つ目の文字列が二つ目の文字列より辞書式順序で手前に来るあるいは等しいかどうか。
`文字列1 > 文字列2`
  現在のロケールにおいて、一つ目の文字列が二つ目の文字列より辞書式順序で後に来るかどうか。
`文字列1 >= 文字列2`
  現在のロケールにおいて、一つ目の文字列が二つ目の文字列より辞書式順序で後に来るあるいは等しいかどうか。

整数に関する判定を行う二項演算子は以下の通りです。

`整数1 -eq 整数2`
  二つの整数が等しいかどうか
`整数1 -ne 整数2`
  二つの整数が異なるかどうか
`整数1 -gt 整数2`
  一つ目の整数が二つ目の整数より大きいかどうか
`整数1 -ge 整数2`
  一つ目の整数が二つ目の整数以上かどうか
`整数1 -lt 整数2`
  一つ目の整数が二つ目の整数より小さいかどうか
`整数1 -le 整数2`
  一つ目の整数が二つ目の整数以下かどうか

バージョン番号を表す文字列に関する判定を行う二項演算子は以下の通りです。文字列のバージョン番号としての比較のしかたは後述します。

`文字列1 -veq 文字列2`
  二つのバージョン番号が等しいかどうか
`文字列1 -vne 文字列2`
  二つのバージョン番号が異なるかどうか
`文字列1 -vgt 文字列2`
  一つ目のバージョン番号が二つ目のバージョン番号より大きいかどうか
`文字列1 -vge 文字列2`
  一つ目のバージョン番号が二つ目のバージョン番号以上かどうか
`文字列1 -vlt 文字列2`
  一つ目のバージョン番号が二つ目のバージョン番号より小さいかどうか
`文字列1 -vle 文字列2`
  一つ目のバージョン番号が二つ目のバージョン番号以下かどうか

他の判定式を組み合わせてより複雑な判定式を作る演算子は以下の通りです。

`! 判定式`
  判定式が偽かどうか (判定式の真偽を逆転します)
`( 判定式 )`
  判定式が真かどうか (判定式の構文上の優先順位を高くします)
`判定式1 -a 判定式2`
  二つの判定式が両方とも真かどうか
`判定式1 -o 判定式2`
  二つの判定式の少なくとも片方が真かどうか

判定式が空の場合、結果は偽とみなします。判定式が (演算子の付いていない) 文字列一つの場合、その文字列が空文字列でないかどうかを判定します。

### バージョン番号の比較

文字列のバージョン番号としての比較は、基本的には現在のロケール情報に従った辞書式順序で行います。ただし、連続する数字は一つの自然数として比較します。また数字とそれ以外の文字との比較では常に数字の方が大きいとみなします。

例えば、`0.1.2-3` と `00.001.02-3` は等しく、`0.2.1` と `0.10.0` とでは後者の方が大きいと判定されます。

## 終了ステータス

Test コマンドの終了ステータスは、判定式の評価結果が真ならば 0、偽ならば 1 です。判定式の構文に誤りがある場合その他のエラーが発生したときは、終了ステータスは 2 です。

## 補足

複雑な判定式は誤って解釈されることがあるので避けることをお勧めします。例えば `[ 1 -eq 1 -a -t = 1 -a ! foo ]` は `[ 1 -eq 1 ] && [ -t = 1 ] && ! [ foo ]` のようにコマンドを分けると式がより明確になります。

POSIX は、エラーが発生した場合の終了ステータスを2 以上と定めています。また POSIX には以下の演算子の規定はありません: `-nt`, `-ot`, `-ef`, `==`, `===`, `!==`, `<`, `<=`, `>`, `>=`, `-veq`, `-vne`, `-vgt`, `-vge`, `-vlt`, `-vle`。