ブログを書きました。我々中年プログラマ諸氏はPerl書けるけど封印しているじゃないですか。シェルスクリプトもそろそろ封印したら良いのではという話です。インターンの人に「この比較のところ、空白が入ると壊れるからクオートして...」とかコードレビューでやりたくない。https://t.co/K9igYPQiqy
— Kazuyoshi Kato (@kzys) 2021年9月15日
ソフトウェア開発者の仕事をしていた頃よりシェルスクリプトに触れる機会が増えた。ソフトウェア開発が職務ではなくなったのだからプログラミング言語を扱う時間が減ったのは当然だし、サーバサイドの技術サポートという仕事柄シェルスクリプトや込み入ったワンライナーを駆使してログを調査したりする機会も多い。シェルスクリプトは苦手なので、しばしば Ruby のワンライナーのお世話になっている(逃げている、ともいう)。
自分が仕事で扱う環境には Ruby がインストールされているので、込み入ったスクリプトを Ruby で書けて助かっているけど、一般的なサーバには Ruby がインストールされていないことも多い。そういう環境でも Perl と Python はだいたいインストールされているのでどちらかを使えばいいわけだけど、その三つの選択肢でジレンマを感じることがある。
Perl はワンライナーで正規表現置換をするとき $_ を書かなくていい*1のがエレガントだし、正規表現の /e (eval) オプションのように Perl ならではの強力な機能もあるが、JSON モジュールが標準添付されていないのが致命的だ。個人的に、二大「頻出だがシェルスクリプトで書くべきではない処理」は正規表現による文字列置換*2・抽出と JSON の扱い*3で、そのうち一方の用途を満たせないのは痛い。
Ruby はシンプルな正規表現置換でも $_.gsub() を書かなくてはいけないのが玉に瑕だが、機能面で不満はないので Ruby が使える環境なら Ruby 一択だ。正規表現の /e (eval) オプションはないが、String#gsub にブロックを渡すとだいたい何でもできるので、ワンライナーとしてはちょっと長くなることもあるがだいたい何とかなる。インストールされていない環境が多い点のみが困りどころだ。
Python は「どこにでもあって JSON を扱える処理系」として便利なのだが、ワンライナーを書きづらいのが難点だ。リスト内包表記を駆使すれば書けないこともないが、向いてないことは否めない。逆に、ワンライナーではないちょっとしたスクリプトを書く場合は、昨今の人気ぶりを考えると、読み書きできる見込み人口の多さという点で Ruby よりも好ましい選択肢なのかもしれない。Ruby を書いてると不思議と「もうちょっと短く・綺麗に書きたい」という欲が出てしまって余計な時間を使ってしまうことも多いので、トータルで考えると一番生産性が高い選択肢である可能性もある。
と、シェルスクリプトの代用品として考えたとき、三種類のメジャーなスクリプト言語にはそれぞれメリットとデメリットがある。問題は、どんな場合にも最善手といえる選択肢はないので、一つの作業のために Perl と Ruby のワンライナーをパイプでつないで使ったりしていると、「いっそシェルスクリプトで全部書いた方が潔いのでは」みたいな気の迷いが生まれることだ。言及先の記事の主張にあるように、awk だの sed だの jq だのを使っていたらそれこそ Perl と Ruby のちゃんぽんどころの話ではないのだが(理屈で考えればスクリプト言語を二つ使う方がずっとマシなのにシェルスクリプトにこだわりたくなってしまうのが「気の迷い」だ、ということ)。
2021/09/18 追記:
件の記事のはてブコメントで、これはと思ったものがいくつかあった。はてブコメントを読みふけるのも随分久しぶりだ。
シェルスクリプトを書くのをやめる - blog.8-p.infob.hatena.ne.jpbashでforを書きたくなったら、perlを使うことにしてる。bashでがんばってもいいことがないので。そしてperlはモジュールをインストールしたくなったら止めてpythonにしてる。
2021/09/16 11:53
これは良い指標だと思った。ちょうどいい塩梅の線引きに思える。自分に置き換えると、Ruby が使える環境では Ruby 一択でよく、Perl と Python しかない環境では「外部ライブラリが必要か」で使い分けると良さそう。実際、Ruby のワンライナーで -r xxx オプションを使うことはよくあるが、Perl のワンライナーで -MXxx オプションを使うことは滅多にない。
余談だが、新しめの Ruby なら bundler が、Python3 以降なら pyvenv がだいたい標準添付されてるので、一時的な用途で外部ライブラリをインストールする手段も確立されているのが便利だ。
シェルスクリプトを書くのをやめる - blog.8-p.infob.hatena.ne.jpShell scriptで書いてたけど、リーダブルじゃないからRubyに変えて、Python嫌いだけどPythonに変えて、今はDenoで書いてる。シェル操作程度で、gemもpipもnpmもいらんかったんや。GoやRustはコードだけ紛失しちゃうから却下
2021/09/16 15:41
Deno に触れている人は他にもいた。Node.js の Ryan Dahl が新しく作った TypeScript の何かだっけ、という程度の理解だったが調べてみたら、コンパイルが不要なスクリプト言語なのに外部ライブラリの参照方法がいい感じにビルトインされていて単一ファイルで動くらしい。単一ファイルで動くパワフルなスクリプトは昔からの夢だった。しかも TypeScript をネイティブサポートしつつ JavaScript も使えるという。TypeScript を全然書き慣れないままなのにはちょっと危機感があったのだが(Node.js や Docker がブームになって普及したときよりも、乗り遅れが後々致命的になりそうな気がしている、Web の仕事を続けていく上では)、かといって Web フロントエンドで使うのは色々設定とか覚えることが多すぎて個人的に細々とやるには難しくて手をこまねいていたところだったので、TypeScript を書く機会を増やすのにもちょうど良さそう。Rust で描かれてるのもモダンでいいし、Deno 自体もワンバイナリで動くのでインストールも簡単と、いいことづくめに思える。
このエントリは、言及先の記事の主張に呼応した内容だし、著者が知人でもあるので、「Re: シェルスクリプトを書くのをやめる」というタイトルでもいいかなと思ったけど、まぁそこまで prominent にしなくても・・・という気持ちが勝って、結局また無題にした。