Skip to content

建立 2026-09-14 更新 2026-09-14

開機設定檔順序

可以想成兩條線:系統開機線(不管有沒有開終端機都會跑)與 shell 啟動線(只有開 Terminal / VS Code 終端機才跑)。兩者不要混在一起改。

系統開機線

flowchart TD
  A[按下電源] --> B[韌體 / iBoot]
  B --> C[載入 macOS 核心]
  C --> D["launchd(PID 1)"]
  D --> E["/System/Library/LaunchDaemons"]
  E --> F["/Library/LaunchDaemons<br/>開機就跑、通常要管理員權限"]
  F --> G[登入畫面]
  G --> H[使用者登入]
  H --> I["/Library/LaunchAgents"]
  I --> J["~/Library/LaunchAgents"]
  J --> K["系統設定 → 一般 → 登入項目"]
階段 位置 何時執行 典型用途
系統 Daemon /System/Library/LaunchDaemons 開機 Apple 自己的服務,不要改
第三方 Daemon /Library/LaunchDaemons 開機、登入前 資料庫、VPN、公司管理工具
所有使用者 Agent /Library/LaunchAgents 任何人登入後 共用的輔助程式
自己的 Agent ~/Library/LaunchAgents 你登入後 個人自動啟動的 plist
登入項目 系統設定 → 一般 → 登入項目 登入後 Raycast、AltTab、通訊軟體

現代 App 大多註冊在「登入項目」,不一定會在 ~/Library/LaunchAgents 看到同名檔。除錯時兩個地方都要看。

舊式 /Library/StartupItems 已過時,新軟體不該再用。

不要把 PATH 寫進 LaunchDaemon 亂猜

開機服務的環境變數跟你在終端機看到的不一樣。背景程式若需要 PATH,應寫在該 plist 的 EnvironmentVariables,而不是指望 .zshrc

登入後還會做的事

  1. 載入輸入法、選單列圖示。
  2. 啟動「允許在背景執行」的項目(系統設定同一頁)。
  3. 套用桌面、Dock、顯示器配置。
  4. 還沒.zshrc。那是開 Terminal 才發生的事。

Shell 啟動線(zsh)

Catalina 之後預設 shell 是 zsh。Terminal.app、iTerm、VS Code 終端機預設開的是「登入 + 互動」shell,讀檔順序如下:

flowchart TD
  A["/etc/zshenv"] --> B["~/.zshenv<br/>每次 zsh 都讀"]
  B --> C{"是否為 login shell?"}
  C -->|是| D["/etc/zprofile"]
  D --> E["~/.zprofile"]
  C -->|否| F{"是否為 interactive?"}
  E --> F
  F -->|是| G["/etc/zshrc"]
  G --> H["~/.zshrc"]
  F -->|否| I{"login?"}
  H --> I
  I -->|是| J["~/.zlogin"]

重點有兩個:

  1. /etc/zprofile 會跑 path_helper。它讀 /etc/paths/etc/paths.d/*,再重組 PATH。所以你在 .zshenvexport PATH=... 的結果,常常被這一步覆蓋或重排。
  2. Homebrew 官方建議把 brew shellenv 放在 ~/.zprofile,就是為了接在 path_helper 之後。細節見 環境變數與 PATH

非互動腳本(例如 zsh script.sh)只會讀 zshenv不會.zshrc。CI 或 launchd 跑的腳本也讀不到你在 .zshrc 寫的 alias。

關機時

zsh 若為 login shell,離開前會讀 ~/.zlogout。系統層則由 launchd 卸除 Agent / Daemon。一般使用者不必改這一段。

自己查目前狀態

# 哪些 LaunchAgents 有載入
launchctl list | head

# 這個 shell 是不是 login / interactive
echo $0
[[ -o login ]] && echo login
[[ -o interactive ]] && echo interactive

# zsh 實際讀過哪些設定檔(除錯用)
zsh -xl

zsh -xl 輸出很長,用它確認「這個檔到底有沒有被讀到」。

相關資料