答え: 最初から
最初の touch コマンド
FreeBSD の touch のマニュアル曰く、touch コマンドは Version 7 の AT&T UNIX で登場したそうです。
HISTORY A touch utility appeared in Version 7 AT&T UNIX. touch(1) - FreeBSD Manual Pages
このときの man を読むと、すでに「ファイルが存在しなければ作成する」ということが記載されています。
DESCRIPTION
Touch attempts to set the modified date of each file. This is done by reading a character from the file and writing it back. If a file does not exist, an attempt will be made to create it unless the -c option is specified.
Touchは、それぞれのファイルの修正日時の設定を試みます。 これは、ファイルから文字を読み取り、それを書き戻すことによって行われます。 ファイルが存在しない場合、-c オプションが指定されていない限り、ファイルの作成を試みます。
unix-history-repo/touch.1 at Research-V7 · dspinellis/unix-history-repo · GitHub
ソースコード1を読むと、たまたまファイルがなければ作るようになったのではなく、あえてそのように実装していたことが分かりました。
具体的には、まず stat(3)
でファイルの存在を確認して、なければ create(3)
でファイルを作るという実装をしていました。
unix-history-repo/touch.c at Research-V7 · dspinellis/unix-history-repo · GitHub
#include <sys/types.h> #include <sys/stat.h> touch(force, name) int force; char *name; { struct stat stbuff; char junk[1]; int fd; if( stat(name,&stbuff) < 0) if(force) goto create; else { fprintf(stderr, "touch: file %s does not exist.\n", name); return; } if(stbuff.st_size == 0) goto create; if( (fd = open(name, 2)) < 0) goto bad; if( read(fd, junk, 1) < 1) { close(fd); goto bad; } lseek(fd, 0L, 0); if( write(fd, junk, 1) < 1 ) { close(fd); goto bad; } close(fd); return; bad: fprintf(stderr, "Cannot touch %s\n", name); return; create: if( (fd = creat(name, 0666)) < 0) goto bad; close(fd); }
では、なぜファイルが存在しない場合にエラーにするのではなく、ファイルを作るようにしたのでしょうか。
それは、わかりませんでした(ぇ
まとめ
いかがでしたでしょうかw
ソースコードにコメントはなく、なぜこのような仕様にしたのかはこのコードを書いたDennis M. Ritchie氏2しか知る由がなさそうです。ただ、2011年に亡くなられたので、もはや聞くことはできません…。
おそらく、その方が便利だからだとは思うのですが、確証がありません。
もしかしたら本か何かに、その意図が残されているかもしれません。
ご存じの方がいましたら、情報をお寄せいただければと思います。