読者です 読者をやめる 読者になる 読者になる

Bye Bye Moore

猫マンション建築の野望を胸に零細事業主として資本主義の荒波に漕ぎ出したアラサー男の技術メモ

UNIXコマンド「test」が思ったより使える件

一般に、「test」はファイルが存在するか確認する際に使われるコマンドです。
結果は標準出力ではなくコマンドの終了状態に格納されるため、注意が必要です。

$ test -e aasm_sample.rb ; echo $?

とまぁ、これ単体だとイマイチありがたみがわかりませんが
設定されている書式を使うと色々便利な事ができます。

より新しい、より古い

より新しいファイルを検索したい場合、以下のように「対象ファイル -nt 比較ファイル」の順で呼び出します。

$ test aasm_sample.rb -nt sample1.rb ; echo $?
0

逆に、古いか判断したい場合は「対象ファイル -ot 比較ファイル」の順です。

$ test aasm_sample.rb -ot sample1.rb ; echo $?
1

空か内容があるか

$ touch hoge.log

と空ファイルをつくったとします。ファイル自体は存在しますが、何もありません。
この場合、空ファイルか確認するのは -nオプションです。

$ test -n hoge.log ; echo $?
0

一方、何か入っているか確認する場合は-zオプションを使います

$ test -z hoge.log ; echo $?
1

エイリアス?について

UNIXの部屋 コマンド検索:test (*BSD/Linux)を見ると

この [ というのは実はコマンドで、またの名を test という

とあり、シェルのif文で使われていたアレが、実はtestのエイリアスだった事がわかります。
ためしに、冒頭のコマンドを再現すると…

$ [ -e aasm_sample.rb ; echo $?
bash: [: missing `]'
2

とエラーがでますが

[ -e aasm_sample.rb ] ; echo $?
0

とちゃんと閉じると結果を出します。
コマンドでも、末尾を見るやつがあるんですね…
ためしに、シンプルなままで美しいと評判のPlan9のtestコマンドソースをみても

/*
 * POSIX standard
 *	test expression
 *	[ expression ]
 *
 * Plan 9 additions:
 *	-A file exists and is append-only
 *	-L file exists and is exclusive-use
 *	-T file exists and is temporary
 */
/* 中略 */
void
main(int argc, char *argv[])
{
	int r;
	char *c;

	ac = argc; av = argv; ap = 1;
	if(EQ(argv[0],"[")) {
		if(!EQ(argv[--ac],"]"))
			synbad("] missing","");
	}
	argv[ac] = 0;
	if (ac<=1)
		exits("usage");
	r = e();
	/*
	 * nice idea but short-circuit -o and -a operators may have
	 * not consumed their right-hand sides.
	 */
	if(0 && (c = nxtarg(1)) != nil)
		synbad("unexpected operator/operand: ", c);
	exits(r?0:"false");
}

/* 後略 */

と、閉じる記法はそのまま残っている事がわかります。
また一つ勉強になりました。