2023年8月9日水曜日

Deno のコマンド実行を改めて考える

Deno でコマンド実行したいと思った時、zx を使うと簡単です。 しかし zx にもいくつか実装の選択肢があり、微妙に仕様が違って毎回迷うので、まとめておきます。

stdout, stderrr の調整

zx-denobazx は stdout, stderr の調整がしにくいので、 複雑なコマンドになるとやや使いにくいです。


コーテーションの自動挿入

dzxdax はコーテーションを自動で挿入します。
await $`sd -f m "${from}" "${to}" ${files.join(" ")}`
上記コマンドは dzx だとたぶん実行できません。 dax は以下のように書けます。
await $`sd -f m ${from} ${to} ${files}`;
これを凄いと感じるか、微妙と感じるかは人それぞれ。 私はライブラリ依存すぎると思うので、後者の立場です。ただ良いところもあります (下)。


コマンド置換

コマンド置換は bash の機能を活かした $() 記法のことです。
await $`sd -s "${from}" "${to}" $(fdfind --type file -e html .)`;
自動で使えると嬉しいですが、dzx, bazx, dax は動きません。 ただ bash の機能を使わずにスペース区切りで展開したほうが依存が少なくて良いかも知れません。 書き換えると以下になるでしょうか。ダブルコーテーションを付けるのが面倒ですね。 あと何気なく "${from}" と書いていますが、from の中にダブルコーテーションがあった時に失敗する問題があります。
const targets = await $`fdfind --type file -e js -e html .`;
const files = targets.split("\n").map((target) => `"${target}"`).join(" ");
await $`sd -s "${from}" "${to}" ${files}`;
dax ならこの処理は自動でやってくれるので、以下のように書けます。 ${from} 部分を自動でエスケープしてくれるので、ダブルコーテーションのバグが発生しにくいのも良いところです。 コマンド数が増えると楽になるかも知れません。 ミスを自動で排除できる点では dax が優れていると思います。
const files = await $`fdfind --type file -e js -e html .`.lines();
await $`sd -s ${from} ${to} ${files}`;

その他

他にも bash の機能を使えるかどうかは、大きな差になってきます。 たとえば dax だと find *.js みたいなことができません。 これは結構多くのケースで大きな課題だなと思いますし、bash 依存を断ち切るのは本当に大変だなとつくづく感じます。

まとめ

個人的な好みでは deno-dx が一番好きで利用していますが、 ミスの排除を自動化できる点では dax が優れているとは感じます。 deno-dx は実装がコンパクトなのが良いところですが、 非推奨になった Deno.run() を使っているので Deno 2.0 になったら対処が必要そうです。 Deno.Command() を使っているライブラリは dax しかないのが辛いところ。 たかがコマンド実行、されどコマンド実行…。

追記: 気付いたら本家の zx が Deno で動くようになっていて、上記の問題はだいたい解決されていました。 Deno 1.40 から deprecated warning がうるさくて大変になってきたので、本家 zx を使い始めました。

0 件のコメント: