zsh 環境設定ファイル
.zshrc
だけでなく .zprofile
など起動時に読み込まれるファイルはいくつもあります。設定はどこに書くべきなのか、どの順でいつ読み込まれるのか迷ったことはありませんか?私は完全に混乱していたので整理してみました。誰かの参考になれば幸いです。
この文書で使う前提語
- zsh-ui 提示: 画面に対話操作を出す起動形態。
- zsh-ui 非提示: 画面に出さず、コマンドを実行して終える起動形態。
- 重い初期化(Init-once): 1回だけ動かしたい初期化。
- 初期状態継承: すでに構成済みの環境(主に環境変数)を起動側から受け継いで zsh を重ねて起動すること。
-
~/.zlogin
/~/.zlogout
は歴史的なファイル名であり、本稿での概念上の“ログイン/ログアウト”とは無関係。
起動形態と読み込み順
重い初期化 | zsh-ui提示 | 目的 | その時点での土台 | その起動で新たに読むもの(順序) | 読まれないもの | |
---|---|---|---|---|---|---|
S1 | ✓ | ✓ | 重い初期化して対話操作を出す | 親から受け継いだ環境(主に環境変数) | ~/.zshenv → ~/.zprofile → ~/.zshrc → ~/.zshrc_mine → ~/.zlogin |
none |
S2 | ✓ | 重い初期化してコマンド実行のみで終了 | 親から受け継いだ環境 | ~/.zshenv → ~/.zprofile → ~/.zlogin |
~/.zshrc |
|
S3 | ✓ | 既存の環境(PATH 等)を土台に対話操作を出す | 親の zsh から受け継いだ環境(PATH など)。環境変数は継承されるが、エイリアス/関数等は新規起動側で再設定が必要 | ~/.zshenv → ~/.zshrc → ~/.zshrc_mine |
~/.zprofile (再実行されない), ~/.zlogin
|
|
S4 | 重い初期化も対話操作もなしでコマンド実行のみで終了 | 親の zsh から受け継いだ環境 | ~/.zshenv |
~/.zprofile , ~/.zshrc , ~/.zlogin
|
ファイル別解説
1) ~/.zshenv
-
ひとこと説明
- どの形態でも常に必要な基礎環境を提供する最小の土台。PATH の最小構成・機密(トークン/鍵)などを置く場所。
-
呼ばれるきっかけと読み込み順
- S1/S2/S3/S4 のすべてで、その起動に入った時点で必ず読み込まれる。
- 以降の処理は、このファイルで用意した基礎環境を土台として積み上がる。
-
.zshrcに集約していい?
-
S2/S4(zsh-ui 非提示)では
~/.zshrc
が読まれないため、PATH や機密が欠落し、非対話の実行が失敗する(コマンド未検出、認証不可等)。 - 基礎環境はここに残す必要がある。
-
S2/S4(zsh-ui 非提示)では
-
私が改名するなら
~/.config/zsh/00-env/00-env-always.zsh
2) ~/.zprofile
-
ひとこと説明
- **重い初期化(Init-once)**を担う層。1回だけ行いたい設定や初期構築(例:一度だけの探索やキャッシュ生成など)を最小限で置く。
-
呼ばれるきっかけと読み込み順
-
S1/S2 で
~/.zshenv
のあとに読み込まれる。 - S3/S4 では再実行されない(初期状態継承のため)。編集の反映確認には S1 または S2 での起動が必要。
-
S1/S2 で
-
.zshrcに集約していい?
- 初期化処理が S1 だけでなく S3 のたびにも動くようになり、対話操作の起動が毎回遅くなる。
- 加えて、S2/S4 では
~/.zshrc
が読まれないため、初期化自体が実行されず整合性が崩れる。
-
私が改名するなら
~/.config/zsh/10-init/10-init-once.zsh
3) ~/.zshrc
-
ひとこと説明
- zsh-ui の挙動(補完・表示・キーバインド等)を司る薄い操作層。
- 個別設定はここから分離して
~/.zshrc_mine
を呼ぶ。
-
呼ばれるきっかけと読み込み順
-
S1/S3 で
~/.zprofile
(S1 の場合)や、既存の土台(S3 の場合)の上に読み込まれる。 - S2/S4 では読まれない。
-
S1/S3 で
-
.zshrcに集約していい?
- 基礎環境(PATH/機密)までここへ集約すると、S2/S4 で未読のため非対話の実行が破綻。
- 重い初期化まで集約すると、S3 のたびに重くなる(体感遅延・無駄な I/O)。
-
~/.zlogin
相当の出力系まで集約すると、S3 でも毎回出力が混入し、自動処理のログや JSON 出力を汚染する。
-
私が改名するなら
~/.config/zsh/20-interactive/20-ui-interactive.zsh
4) ~/.zshrc_mine
-
ひとこと説明
- 個人の操作感(履歴設定、補完拡張、エイリアス、関数等)を基盤と分離して管理し、配布物の再現性と保守性を高める。
-
呼ばれるきっかけと読み込み順
-
S1/S3 で
~/.zshrc
から明示的に呼び出される。
-
S1/S3 で
-
.zshrcに集約していい?
- 基盤と個人差が混在し、共有配布やレビューが困難になる(差分の可視性低下、使い回し不可、環境ごとの再現性悪化)。
-
私が改名するなら
.config/zsh/20-interactive/21-ui-user-interactive.zsh
5) ~/.zlogin
-
ひとこと説明
- zsh-ui 提示の仕上げとして一度きりにしたい軽微な処理(例:簡易メッセージ)を置く場所。標準出力の副作用は極力避けるのが安全。
-
呼ばれるきっかけと読み込み順
-
S1 では
~/.zshrc
の後に、S2 では~/.zprofile
の後に読み込まれる。 - S3/S4 では読まれない。
-
S1 では
-
.zshrcに集約していい?
-
~/.zshrc
は S3 でも読まれるため、本来一度きりにしたい処理が毎回実行され、不要な出力が対話画面や自動処理のログ/結果に混入する。S2/S4 では逆に未実行となり、挙動が不統一になる。
-
-
私が改名するなら
~/.config/zsh/30-postinit/30-postinit-once.zsh
6) ~/.zlogout
-
ひとこと説明
- 一度きりの後片付け(ログ整理等)を担う終端層。
-
呼ばれるきっかけと読み込み順
- S1/S2 のように重い初期化で起動した zsh が終了するときに読まれる。
- S3/S4 の終了時には読まれない。
-
.zshrcに集約していい?
- 起動時に後片付けの処理が紛れ込み、状態破壊や不可解な出力を引き起こす(開始直後にクリーンアップが走る等)。
- S3 でも都度実行されてしまい、意図しない反復やログ汚染が起こる。
-
私が改名するなら
.config/zsh/90-exit/90-exit-once.zsh