はじめに
なぜ macOS は bash の上位互換でもない zsh を標準の対話シェルにしたのでしょうか? その理由は多くの場所で繰り返し言われているので、ここには書きません。ここでは zsh はどんなシェルなのかを簡単に説明します。
zshは1990年に誕生した古いシェル
zsh は古いシェルです。bash のリリースはベータ版として 0.99 が 1989年6月8日、zsh 1.0 のリリースはその 1年半後の 1990年12月15日です。ちなみに Linux の誕生が 1991 年です。
古いから悪いと言っているわけではありません。現在までずっとメンテナンスと機能強化が続いているので問題ありません。ここで言いたことは、
zsh は最近作られた新しいシェルなんかじゃない
ってことです。bash と同じぐらい古いシェルです。
zshはbashの上位互換シェルではない
まあ、大抵の人は公式ドキュメントなんて読まないですよね?
さすがに面倒なので ChatGPT に直訳させました。太字は私の手によるものです。
2.8: なぜ bash スクリプトを zsh で実行するとエラーになるのですか?
要約:bash は zsh のリファレンス実装ではなく、zsh は bash のバグごと互換の再実装ではありません。bash と zsh は異なるプログラミング言語です。互換性はなく、一般的に、どちらかの言語で書かれたプログラムは他方では動作しません(この状況は、Python 2 と Python 3、C と C++、さらには C89 と C11 など、他の多くの密接に関連した言語の組み合わせとも似ています)。
同じ入力に対して bash と zsh が異なる動作をする場合、それが zsh のバグかどうかは、bash の動作によって決まるのではなく、zsh のユーザーマニュアルに何が書かれているかによって決まります。(比較として、Emacs で :q! を入力しても終了しないのはバグではありません。)
とはいえ、bash と zsh の言語には共通のサブセットが存在し、両方で動作する非自明なコードを書くことも、両方に精通していれば可能です。しかし、bash の動作と zsh の動作が異なるからといって、zsh にバグがあるとは限りません。その違いは、zsh のバグである可能性も、bash のバグである可能性も、どちらにもバグがない可能性もあります(例については 3.1 を参照)。
これらの違いにどう対処するかは、コードの種類(スクリプトかプラグインか)によって異なります。
スクリプトの場合 ― $PATH にある外部コマンド、または /etc/rc.d/sshd や ./configure のようにパスを明示して実行するもの ― 答えは簡単です:
bash スクリプトは zsh で実行しないでください。 そのスクリプトが bash 用に書かれたものであれば、bash で実行してください。zsh を対話シェルとして使っている場合でも、スクリプトに #!/usr/bin/env bash を書いておくことに全く問題はありません。
実際、最近 zsh に乗り換えたばかりであれば、しばらくの間はスクリプトを #!/usr/bin/env bash のままにしておくことをおすすめします。そうすれば移行が段階的になり、学習曲線が緩やかになります。zsh に慣れてきたら、各スクリプトを zsh に移植するか、現状のまま維持するかを決めてください。
プラグインの場合 ― . や source、autoload ビルトインで読み込まれるシェル内部で実行されるコード、.zshrc に追加されるコード、またはシェルプロンプトに直接貼り付けられるコード ― の場合は、bash と zsh の両方で動作するように努力する価値があるかもしれません。しかし上述のとおり、それには両方のシェルに精通している必要があり、両者の違いを避けるか、if test -n “$ZSH_VERSION” のような条件分岐で明示的に対応する必要があります。
まとめると、bash スクリプトやプラグインを zsh で実行したいのであれば、それを正しく zsh に移植しなければなりません。両言語の違いを一行ずつ見直し、それに応じて調整してください。それはちょうど、アメリカ英語の本をイギリス英語に翻訳するようなものです。
zshでデフォルトはPOSIX準拠じゃない
zsh は POSIX シェルをエミュレートできますが、デフォルトでは POSIX 互換ではありません。とちゃんと書いてあります。
Zsh is able to emulate POSIX shells, but its default mode is not POSIX compatible, either.
だから、macOS の /bin/sh
は今でも(ほぼ)POSIX 互換の bash なんですね。もっとも POSIX.1-2024 には対応していませんが。
zshはksh88とtcshの中間
zsh は基本的には ksh88 ベースです。
zsh は ksh、bash、tcsh、sh、csh を参考に、 ksh と tcsh を合わせたシェルにしようとして開発が始まりました。
なぜ bash の上位互換にしなかったのかって?
当時の bash は Bourne シェルの上位互換であり ksh88 の機能を取り込んだシェルとして開発が始まったばかりのシェルです。Bourne シェル代替のオープンソースのシェルでしかなく、Linux もない時代に登場した「将来性があるかもわからない bash」の上位互換として作るわけないじゃないですか?
zsh は既存のシェルを参考に独自のシェルを作りました。設定でかなり ksh に近づけますが、デフォルトでは ksh には近くなく、したがって bash とも近くありません。
「z」はZ戦士ではなく人の名前の頭文字
zsh は最強や究極を自称してませんよ?
zsh の z というのは人の名前 Zhong Shao の頭文字です。zsh の開発者は当時プリンストン大学に在学していた の Paul Falstad ですが、ティーチングアシスタントが Zhong Shao で、ログイン名「zsh」がシェルの名前として良いと考えたそうです(Paul Falstad が Zhong Shao のアカウントを利用していた?)。
The name ZSH derives from Zhong Shao, teaching assistant at Princeton
university (now [2004] at Yale). Paul Falstad thought that his login
name, “zsh”, was a good name for a shell.Hier is the link (search for “Zhong Shao”)
zsh は強力なシェルですが、最強や究極なんて自称していないはずです(もし書いてあったら教えて下さい)。最新版の機能は強力ですが、機能が少ない作りはじめの時点で最強なんて自称する訳ありませんし。究極のシェルを作ろうといたわけではなく、単なる Z(hong) Shell です。
最初に言い始めたのは誰か知りませんが、zsh の z が最強や究極の意味だと主張しているのはこの本でしょう? それはこの本が勝手に言ってることですよ。
zshは、これらを凌駕する最強のシェルで(「z」は「究極の」という意味)、
ざっとこの本を確認しましたが、この本には Zhong Shao の名前は書いてないようなので、おそらく著者は知らなかったのでしょう。
ちなみに、英語の z にも最強や究極なんて意味はないはずです(ないですよね?一応調べましたけど)。最後という意味はあるようですが。
なお、某漫画・アニメでは Z は、原作者(神)が「もう終わり、これ以上続きは書きたくない!」ってことでアルファベットの最後の Z をつけたけど、それがいつの間にか究極の意味にすり替えられたと私は認識しています。
おわりに
みんな、シェル (zsh) のことにあまり興味ないんだろうなーって思います。私としては、いや、なに、みんな勘違いしてるの???っていつも思ってるので書きました。
Views: 0