仕事でsedのコードをパパッと書いて使ったら、コードレビューで動かんと言われてしまった。そういえば、同僚はMacで、おれはLinuxだったな。
まぁsedならよくある話なので、しょうがないと思ってawkで同じことをした。awkは比較的もうちょっと互換性がある気がしているからだ(どっこいどっこいな気もする)。
しかしまだ動かないと言う。もう、大絶叫だ。アー。おしまいだ。カスがよ〜〜〜と思いつつ(社会人なので絶叫はしない)、よく調べてみるとmakeの互換性だった。というのも、試しにbrew install make
してGNU Makeで試してみてくれ、と言ったら、あっさり動いたからである。実はsedもawkも悪くなくて、そいつを呼び出してるmakeに互換性がなかった。ごめんな、お前たち悪くなかったよ。でもそれはそうと互換性はない。
define foobarstring ... endef # ... $(file > $@,$(foobarstring))
こういう構文がある。makeではdefine
つう構文があって、複数行にまたがった内容の変数を書ける。そいつを$(file)
するとファイルシステムに書き出すことができるわけだ。おれは共通のヘッダを特定のファイルに書き込みたかったので、とりあえずMakefile
に変数として持っておいたわけだ。
しかしどうもfile
は互換性がないらしく、同僚のマシンだと上書きじゃなくて追記として振る舞うらしい。もううんざりだ。うんざりザリガニ
しょうがないから共通のヘッダはファイルに最初から書き出しておいて、cat
でリダイレクトするようにした。
cat foobarfile > $@
これでようやくLinuxでもmacOSでも動くようになった。そのかわり、makeからしか読まれないファイルがファイルシステムに1つ増えた。
なんか、こういうことがよくあるんだよな。sedやawkに互換性があまりないのは周知の事実なので、perlを使うといった賢い回避策がある。でも、sedで一瞬で書けるようなtrivialな例 --- 例えば1〜3行目だけ削除する(sed -e '1,3d'
) --- のために、perlでどれだけのワンライナーを書けばいいのだろう。この場合、目的にとって、perlはあきらかに牛刀だ。おれがやりたいのは3行消すというニワトリみたいなタスクなのであって、わざわざperlを使いたくはないんだよな・・・(それはそうと、perlは大抵のマシンに入ってるから、互換性のことはあまり考えなくてもいい)
GAFAあたりのイケイケエンジニアが、sed / awk / makeの完全上位互換みたいなやつをRustかなんかで書いて、互換性を破壊していってほしい。もしくは、とっとと全部gsed / gawk / gmakeで統一してほしい。
教訓としては、makeとかsedで難しいことしちゃダメ、ということになるのだろう。それは一面的にはまったく正しい。他人に教育するならおれもそう言うだろう。あきらめてperlだかrubyだかを呼び出してくれ。それか、おれがLinuxを捨ててmacOSを使うか、vice versaだ。でもそれはシステムの多様性を破壊するし、俺は好まない。両者が互いに良い影響を及ぼして現代のソフトウェアを支える技術が生まれてきたからだ。DockerはLinuxから来たし、すぐれたUIはmacから来てる。
しかし、ごく基礎的なツールチェインが、本当に基礎的なことしか安全にはできなくて、ちょっと発展的なことをしようとするとすぐ壊れるのは、普通に考えてありえない。ちゃんと動いてくれよ。単純なことを確実に遂行するための道具が、道具として信頼できないのは致命的だ。
それはそうともうどうしようもない。おれたちはtree shakingとかWASMとかコンテナとか、すごい技術の上で暮らしている一方、makeは壊れるし、sed -i
はちゃんと動かない。