Committerをしていながら今頃気づくのもどうかと思うが、#!行解釈がFreeBSD 6.0以降変わったことを知った。正確にはsys/kern/imgact_shell.cのrev1.33で変更されている。ガーン。リリースノーツには載ってなかったよ。

 つまり、次のようなスクリプトを実行すると:

#!/usr/bin/env ruby -Ke
...

FreeBSD 5.x以前では「/usr/bin/env」「ruby」「-Ke」という3つの引数でexecされるが、6.0以降では「/usr/bin/env」「ruby -Ke」の2つでexecされる。(果たして、動かない)

 ちなみに、懐かしのラクダ本(その後改訂されているが、改訂版に記述が残っているかは知らない)にあった#!行テクニックのうちのいくつかも使えなくなっている。

 旧来の挙動はFreeBSDとBSD/OSくらいのものらしいし、こういうスクリプトは手元でひとつしかなかったのでほとんど実害はなかったが、(FreeBSDで仕様が変更されたことに)少し驚いた。まあ、きっぱり諦めるのがいいだろう。そもそも、env(1)をかませたりするささやかな移植性への望みは、env(1)/binにあるいくつかの環境の存在で潰えているわけだからね。

 SunOSだとエラーにはならず、黙って2番目以降の引数がtruncateされるので、知らないとはまるかもしれない。まあ、FreeBSDやBSD/OSで育った人だけかな。昔、ラクダ本を片手にPerlに熱中していた頃、長くなりすぎたone-linerを#!/usr/bin/perl -naF: -i.origのようなスクリプトに書き換えたら動かず、熱くなったのは懐かしい思い出。

 #!機構(the shebang mechanism)については、”#! – the Unix truth as far as I know it.“や”The ‘#!’-magic, some details about the shebang mechanism on various Unix flavours“に詳しい記述があるので参考まで。後者については最近もメンテナンスされているので、FreeBSD 6.0での変更について著者に教えてあげた。そのうち反映されるでしょう。

→返事が来ました。さっそく更新されています。すばらしい。


Categories : Tech