macOS ログインシェル

他の Unix システムでは、ターミナルエミュレーターは通常 非ログインシェルで起動されます。さまざまな理由により、macOS では すべてのターミナルが既定でログインシェルになります。

Ghostty は macOS の伝統を尊重し、各シェルをログイン シェルとして起動します。これは macOS の他のターミナルエミュレーター(特に 既定の Terminal.app)の振る舞いと一致します。しかし、この振る舞いは 他の Unix システムとは異なっており、 その挙動に慣れたユーザーには混乱を招くかもしれません。

なぜログインシェルなのか

伝統的に、UNIX シェルには、ユーザーがシェルを操作できるようになる前に 実行されることを期待される 2 つの主要なファイルがあります:プロファイルファイルと rc ファイルです。 プロファイルファイルは通常ログイン時に一度だけ実行され、ユーザーの 環境のセットアップに使われます。rc ファイルは新しいシェルの作成のたびに実行され、 シェル自体の設定に使われます。

例として zsh(macOS 10.15 以降の既定シェル)を考えてみます: zsh は .zprofile と .zshrc ファイルを使います。多くの Linux システムでは、.zprofile (または類似のもの)が、デスクトップマネージャーなどによる初回ログイン時に 実行されます。これにより以降のシェルは、環境と .zprofile が行ったあらゆるセットアップを継承できます。ここでの考え方は、 コストのかかる初期化はログイン時に一度だけ行えばよく、以降のシェルは そのセットアップ処理のすべてを再利用できる、というものです。

Note

例として zsh を挙げましたが、ほぼどんなシェルを代わりに使っても同じ 振る舞いになります。bash が例外です。Bash は、シェルが インタラクティブかつ非ログインである場合に のみ .bashrc を読みます。macOS が tcsh から bash へ OSX 10.2 Jaguar で移行して以来、この bash の違いが 見落とされてきた可能性があり、その結果、開発者はシェルのセットアップを すべて .profile に書くようになりました。.bashrc はめったに実行されず、 特に新しいターミナルを起動することでは実行されないからです。今では zsh が新しい既定になったため、 インタラクティブな非ログインシェルを起動するたびに .zprofile と .zshrc の 両方が呼ばれます。

macOS で異なるのは、システムへのログインに使われる GUI が .zprofile を実行しないことです。システムレベルのグローバル 設定を読み込む独自の方法を持っているためです。つまり、どのターミナル エミュレーターもシェルをログインシェルとして実行しなければならず、 さもないと新しいシェルは .zprofile でのセットアップ処理を欠いた 状態で壊れてしまう可能性があるということです。これは不幸な現実ですが、 .xsession や同様のものは存在しない(.zprofile は実行されない ため)以上、ユーザーのターミナルに初期設定へのアクセスを与えたり、 1 あたりのグローバル環境変数のようなものを設定したりする 手段がないことを考えれば理にかなっています。

しかしこれは、すべてを .zprofile に入れればよい、あるいは この 2 つのファイルが常に一緒に呼ばれる、という意味ではありません。zsh は ログインモードかつインタラクティブモードで起動されるため、.zprofile と .zshrc は 新しいターミナルが作成されるたびに毎回実行されます。しかし、ターミナル エミュレーターの中でシェルを実行すると、それは単にインタラクティブシェルにすぎず、 .zprofile で初期化された親シェルの設定へのアクセスを失います。これは .zprofile にエイリアスを置き、ターミナルインスタンスを起動して そのエイリアスを実行し、その後 zsh を実行すると エイリアスがもはや利用できないことで確認できます。

したがって、ほとんどのシェルの設定は .zshrc ファイルに入れておくべきです。 そうすれば、どんなシェル(ターミナルであれそうでなかれ)でも正しく 初期化されます。これは他の Linux システムの dotfiles の 書き方ともいくらか一致します。

Footnotes

  1. Why are interactive shells on OSX login shells by default? ↩