26 April '2007 - 13:59 | 技術動向 左から右へと受け流す
ムーディ勝山は「右から左へと受け流す」と歌っているけれど、それとは正反対の方向に受け流すのがプログラマの流儀。
つまり、式は左から評価されていくのが正しいし、それこそが期待される動作。評価の順番は処理系におまかせという言語もあるけれど、今時、そんなものを使う必要はない。って、いまの僕はそれがメインの言語なのだけれど。
って、何の話かと思いきや、なんのことはない、find という便利なコマンドの話で、こいつも例外じゃないよ、という話。
$ ls
aaa.c bbb.c ccc.c ddd.c eee.c fff.c foo.c fubar.c
$ find . -name 'f*.c' -print
./fff.c
./foo.c
./fubar.c
$ find . -print -name 'f*.c'
.
./aaa.c
./bbb.c
./ccc.c
./ddd.c
./eee.c
./fff.c
./foo.c
./fubar.c
と、これを見て全く意味が分からない人は、たぶんこのコマンドの対象外なので以下は読む必要ないです。なにかの間違いで「黒いウィンドウ」が開いたら、びっくりしてポチっと閉じるのが吉。
というわけで、上のコマンドの最後のやつが問題。そう、'f*.c' が効いてない。
これはなぜかというと、-print ってのは、なんでも条件を true にしてしまう効果があるので、最後に書かないと意味がない。他には、-print0 と -ls も同じ効果があるので、これらも条件式の最後に書かないと意味がない。
だから、たとえば、「いまどきfindとxargsを使う時は-print0と-0を忘れずに」で紹介されている
find . -type f -print0 -name '*~' | xargs -0 rm
なんてことをやった日には、えらいことになります。
emacs が作ったバックアップファイルを全部削除しようと思って上のコマンドをコピペして実行すると、-name '*~' の評価を待たずに -print0 されてしまうので、バックアップファイルだけでなしに、あなたのファイルは「全部」消去されてしまいます。そこに残るのは空っぽのディレクトリだけという無惨な状況になるわけですね。南無阿弥陀仏。
まあ、不用意に rm コマンドを打って死亡するということは、誰しも通る、そして通らねばならない道です。ぼくも、rm -rf とタイプしたら、なぜかそこが / で、ぼくも root だった、ということを過去に二度ほど経験して立派な大人になりました。
まあ、otsune さんは、ちゃんと検証せずにコピペでコマンドを実行すると痛い目に遭いますよってことを教えたかったのかも知れないし、そうだとしたら余計なことをしてしまってるのかも知れない。
go55man () (ウェブサイト) - 26 April '2007 - 15:53
ちなみに、ムーディーではなく、ムーディです。何かの番組で本人がそう明言してました。
ひろしま - 26 April '2007 - 16:16
とりあえず放置しとくと害があるので、私の日記の方はこの件を追記の上で訂正します。
otsune (ウェブサイト) - 26 April '2007 - 23:47