シェルスクリプトの代替

要約:決定版はとくにない。

kzys氏のシェルスクリプトを書かないという記事は面白かった。 https://blog.8-p.info/ja/2021/09/15/bash/

シェルスクリプト、ごくたまに書くことはあるが、ほんともう細かい話とかはすべて忘れているし、覚える価値を感じない。いまさら覚える必要のない技術だなと感じる。が、その一方でなかなか代替品がないようなニッチでもある。

自分は必要に応じてPythonかRubyか、といったあたりを使うことが多いが(perlはもう書けなくなった)、なかなかこれという感じには思い至らない。なにがいいんだろうね?という。

前提条件:インタラクティブな環境(REPL)はなくてもいい。そこはもう既存のシェルでいい。自動化したシェルスクリプト的なタスク記述を目標とする。bashの置き換えという意味では「どこにでもインストールされていることを前提にしないといけない」という問題もあるが、そこも問わない。自分が個人的に、またはチーム内の人に使ってもらうぐらいの規模で考えるので、コマンド一発でインストールできるか、コンテナイメージで実行できるぐらいであればもう良い。それ以上のことは検討しない。bashには勝てません、で終わってしまうので。

Python / Ruby

こうした言語をそのまま使うというもの。GoogleではPythonがよく使われていると思う。たとえばChromiumのビルドシステムGNでは補助スクリプトはすべてPythonで書くことになっている。ちょっとした処理をしてフラグを生成したものを渡してコマンドを起動して、その結果をちょっと整形して、といったことをやるには気軽だ。もっと気軽には自分はRubyで書いたりもする。

欠点。まずコマンド起動の部分が関数呼び出しになるのでまあまあ面倒くさい。パイプしたりするのもちゃんと書くのはじゃっかん面倒。そのため、標準出力をそのまま文字列として変数に渡す、みたいなことをしがち。

言語内DSL

Rubyとかの言語機能を使って言語内DSLでなんとかしようという話。Rubyの shell.rb とか。https://ruby-doc.org/stdlib-2.6.3/libdoc/shell/rdoc/Shell.html PerlにもPythonにもいろいろある模様。

またはzxもこれと近いね。https://github.com/google/zx。zxはtagged template stringsを使ってるのがオシャレだな。

欠点。なんか言語機能のabuseっぽくてちょっと嫌。けっきょくスクリプト起動のための依存関係が増えて嬉しくない(shell.rbはその点、標準ライブラリに入ってるので楽。しかしこれを標準ライブラリに入れるのはすごいな)。コマンドと変数名がかぶるとおかしなことになる。パラメータの展開とかいろいろ不安を感じるものも多い。などかなあ。

ワークフローエンジンまたはmake

makeを使うという主張もあった。一種のワークフローエンジン・タスク管理ツールを使うという手もある。Python Invoke http://www.pyinvoke.org/ とかもそれに近いですね。タスクの順番や依存関係とかを簡潔に書ける。外部コマンド実行はpure Pythonなどよりはマシかな。そういや昔、そういうのを使うプロジェクトに関わったことあるなあ。

欠点:書きづらいタイプのタスクもけっこうある。条件分岐とかしだすと、まあできるんだけどとたんに面倒になったり。パイプやコマンドの出力結果の加工とかも考えるとMakeはそれ単体では成り立たない気がする。言語内ワークフローエンジンは言語の機能を使えばまあアリではあると思う。

独自スクリプト言語

上記の欠点をあげつらうならもういっそ独自言語でもいいのかな、という気もする。PowerShell https://docs.microsoft.com/en-us/powershell/ とか、Oil https://www.oilshell.org/ とかのアプローチ。外部コマンド実行やパイプ、典型的な構造データ(JSONなど)の処理は言語処理系内でできるようにすればいい。

欠点:新しい言語や処理系を覚えないといけない。JSONの処理がたとえばビルトインでできても、やっぱりYAMLやXML、TOMLも扱いたいです、みたいになったときに困るかもしれない。

結語

というわけで、これが絶対いいっていうのはないんだよな、と思う。個人的には言語内DSLがいいかなあと思うが、その出来にもよるしね。