MSYS の ln

MSYS の ln

大昔からの Windows ユーザで、大昔からの MSYS ユーザで、大昔からの UNIX ユーザであるわたくしが、ある思い込みをしていた、というだけの「ネタ」です。昔話、かな。

今は昔

UNIX には大昔から「ハードリンク」がある。以下画像のような:
ln

ハードリンクは「分身の術」と思えばよろしい。

歴史的には少し遅れて「シンボリックリンク」が出来たのだけれど、それですら「大昔」のことで、ワタシは「若い」ので、シンボリックリンクがなかった時代は経験してない。シンボリックリンクは参照と実体が区別されるし、シンボリックリンクは実体に逃げられる。

で、Windows のファイルシステムにおいては、いわゆる NTFS5 になってはじめて「ハードリンク相当のもの」「シンボリックリンク相当のもの(junction, mountpoint)」がサポートされることになる。これは Windows 2000 の話。

ところが「ハードリンク」は公式に API も提供され、エクスプローラもちゃんとそれを「知ってくれる」のに、junction, mountpoint は DeviceIoControl をダイレクトに叩かないと作れない、という状態がしばらく続いた。記憶では SDK で後から正式な API が登場したはず。

ただ問題は「開発問題」だけではなくて、エクスプローラは junction の存在を「知らない」、というより通常ファイル・フォルダと区別する術がないため、「リンクだけ切る」ことが出来なかった。つまり「junction をやめる」ことが(DeviceIoControlの助けなしには)出来ずに 「指した相手をめでたく消しこみにいく」という危険極まりないもの だった。アイコンオーバレイを自作でもしない限り、作った本人でさえ忘れてそのミスをしでかす。そういうわけでワタシは、hardlink, junction, mountpoint を自在に作れるシェル拡張を作っておきながら、怖ろしくて人には配れなかった。少なくとも Windows XP では。Windows 7 に乗り換えてからは一度も試みていないのでわからない。

記憶では、cygwin が「本物に酷似した ln」サポートは、かなり早かったはず。β版から1.0に向かいつつあったころからそう遠くなかったと思う。その前は Windows 9x 時代のあの「まがいもの」で誤魔化していたのだが。今は junction、作るのかな? 確か。cygwin に嫌気がさした時期とほぼ一致しちゃってるので、わからないけどね。

思い込みの力

長らく日常的に使っていても「思い込み」とは怖ろしいもので、MSYS の ln が「一応ハードリンクはちゃんとしてる」ことに、ついぞ今の今まで気付いていなかった。

MSYS の ln の仕様は、ある意味正解と思う。試したところ、以下のようである:

  • ハードリンク(ln src dest)は本物。UNIXと同じ振る舞い
  • シンボリック(ln -s src dest)は単にコピーするだけらしい

UNIXと同じであって欲しいUNIXラバーズはがっがりするであろうし、イラつくかもしれないが、ワタシは「頼むからそうしないでくれ」と、条件付で思う。条件とはもちろん

  • エクスプローラから識別出来ないならやるな

である。相手がエクスプローラだけならまだいいが、find が平気で無限再起するぞ。find も通常フォルダと区別する術を持たないなら、永遠に潜っていってしまう。

ハードリンクって何の役に立つの?

「分身の術」、なので、「間違って消す心配の少ない場所にハードリンクを置いておく」と、作業場所のものを誤って消してしまっても同じものが残る。これは「バックアップ」とは明確に違う。

なお、ハードリンクを実現する Windows API は調べればすぐ出てくるはず。vba や jscript でも出来るしね。Python なら例えばここね。