Random Tech Thoughts

The title above is not random

zsh+tmux+OS X: 正确地设置 PATH

我在 OS X 上使用 tmux 遇到过两个 PATH 环境变量的问题:

  1. 自己添加的路径总是被放到系统路径之后
  2. 环境变量中的部分路径重复了两遍

以前偷懒一直用 workaroud 避开问题,前段时间终于弄清了原因和解决办法,今天终于有时间写下来。问题的起因得从 zsh 的启动说起,zsh 启动过程会读取如下文件(摘录自 man zsh):

  1. /etc/zshenv
  2. $ZDOTDIR/.zshenv
  3. 如果是 login shell,顺序读取 /etc/zprofile, $ZDOTDIR/.zprofile (未设置 ZDOTDIR 时默认使用 HOME)
  4. 如果是 interactive shell, 顺序读取 /etc/zshrc, $ZDOTDIR/.zshrc
  5. 如果是 login shell, 顺序读取 /etc/zlogin, $ZDOTDIR/.zlogin

zshenv 无论是否为 login shell 都会读取,但设置环境变量我们只需在 zprofile 中完成即可。OS X 在 /etc 目录下有两个一模一样的 zshenvzprofile,我删除了多余的 /etc/zshenv,并在 .zprofile 中设置用户的环境变量。完全抛弃 zshenv 可以减少 zsh 启动时需要读取的文件数,同时避免它对环境变量做出不必要的修改。

PATH 环境变量问题来源于 tmux 默认以 login shell 的方式执行 shell。zsh 作为 login shell 时会执行 /etc/zprofile,而该文件会调用 /usr/libexec/path_helper,根据 /etc/paths 等文件设置系统环境变量。path_helper 会将当前 PATH 环境变量添加到系统环境变量之后,这一行为导致了 PATH 的重复,并且自己设置的路径出现在系统路径之后。

了解问题的根源之后解决办法很简单,在 ~/.tmux.conf 中添加下面选项禁止以 login shell 启动 zsh 即可:

set -g default-command /usr/local/bin/zsh

Comments