Mac默认用zsh,环境变量应按生效时机分工:需登录即生效的(如PATH、JAVA_HOME)写入.zprofile;需每次新开终端都生效的(如alias、PS1、插件)写入.zshrc。.zprofile只在登录Shell时执行一次,.zshrc在每次交互式Shell启动时执行。
mac 默认用 zsh,环境变量该写在哪,关键看“什么时候需要生效”:要一登录就有,写 .zprofile;要每次新开终端都生效,写 .zshrc。两者不是互斥,而是分工明确。
.zprofile:只在登录时运行一次
它相当于“开机初始化”,适用于必须尽早建立、且后续所有子 shell 都能继承的设置。
- PATH、JAVA_HOME、ANDROID_HOME 等全局路径类变量,建议放这里
- conda init、pyenv init 这类一次性初始化脚本,也适合放这里
- Terminal.app 默认启动的是登录 shell,所以它会加载 .zprofile
- 但 VS Code 集成终端、iTerm2 新建 tab(非登录模式)通常不读它
.zshrc:每次打开终端都运行
它管的是“你和终端怎么互动”,适合高频、个性化、交互性强的配置。
- alias ll='ls -alh'、function mkcd() { mkdir -p "$1" && cd "$1"; } 这类命令简写和函数
- PS1 提示符、语法高亮、自动补全插件(如 zsh-syntax-highlighting)
- 它不保证被非交互式 shell(比如脚本)读取,也不适合放 PATH 初始化逻辑
- 注意:如果 .zprofile 没有 source ~/.zshrc,那么登录 shell 启动后可能缺别名
常见误区与实操建议
很多问题其实出在加载时机错配:
- 装了 nvm 却提示 command not found?大概率是把 nvm 初始化代码错放进了 .zshrc,而没在 .zprofile 中确保 PATH 正确——nvm 自身依赖 PATH 才能定位 node
- 改了 .zshrc 没生效?执行 source ~/.zshrc 立即重载;改了 .zprofile 则需新开终端或执行 source ~/.zprofile
- 想让所有场景都生效?可以把环境变量统一提到 ~/.zshenv(极少数必要情况才用,一般不推荐)
- 检查当前 shell 类型:终端里输入 echo $SHELL,输出 /bin/zsh 就说明你在用 zsh


















