【转】Mac OS X 中 Zsh 下 PATH 环境变量的正确设置

在 Mac OS X 中使用 zsh,环境变量 PATH 一不当心就会变得很紊乱,表现为本身设置的路径老是被放到系统路径以后,部分路径还会有重复。这是咱们不太了解 zsh 启动时加载文件的顺序和 Mac OS X 的 shell 类型致使的。linux

zsh 启动过程当中会依次读取如下文件:shell

  1. /etc/zshenv
  2. $ZDOTDIR/.zshenv($ZDOTDIR 未设置时默认为 $HOME)
  3. 若是是 login shell,读取 /etc/zprofile, $ZDOTDIR/.zprofile
  4. 若是是 interactive shell,读取 /etc/zshrc, $ZDOTDIR/.zshrc
  5. 若是是 login shell,读取 /etc/zlogin, $ZDOTDIR/.zlogin

login shell 是用户登录时,输入用户名和密码后启动的 shell,non-login shell 是登陆之后所打开的 shell。interactive shell 在终端上执行,shell 等待你的输入,而且当即执行你提交的命令,跟用户存在交互;non-interactive shell 以 shell script(非交互)方式执行。bash

interactive, login shell 比较常见,咱们 ssh 到远程主机的字符终端时,就是典型的这类 shell。non-interactive, login shell 不多见,一些 X 设置会让你登录,目的仅仅是加载它的相应设置文件。interactive, non-login shell 一般发生在经过已存在的 session 启动一个新的 shell,好比 linux 下的 screen、tmux,linux 下桌面环境启动的 shell 也是这类 shell,好比 gnome shell。non-interactive, non-login shell 很常见,咱们执行 shell script 就是这类 shell。session

1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 
+--------------+-------------+-------------+-----------------+-----------------+ | | login | non-login | login | non-login | | | interactive | interactive | non-interactive | non-interactive | +--------------+-------------+-------------+-----------------+-----------------+ |/etc/zshenv | A | A | A | A | +--------------+-------------+-------------+-----------------+-----------------+ |~/.zshenv | B | B | B | B | +--------------+-------------+-------------+-----------------+-----------------+ |/etc/zprofile | C | | C | | +--------------+-------------+-------------+-----------------+-----------------+ |~/.zprofile | D | | D | | +--------------+-------------+-------------+-----------------+-----------------+ |/etc/zshrc | E | C | | | +--------------+-------------+-------------+-----------------+-----------------+ |~/.zshrc | F | D | | | +--------------+-------------+-------------+-----------------+-----------------+ |/etc/zlogin | G | | E | | +--------------+-------------+-------------+-----------------+-----------------+ |~/.zlogin | H | | F | | +--------------+-------------+-------------+-----------------+-----------------+ | | | | | | +--------------+-------------+-------------+-----------------+-----------------+ | | | | | | +--------------+-------------+-------------+-----------------+-----------------+ |~/.zlogout | I | | G | | +--------------+-------------+-------------+-----------------+-----------------+ |/etc/zlogout | J | | H | | +--------------+-------------+-------------+-----------------+-----------------+

那么问题来了,在 Mac OS X 中打开 iTerm.app 或者 Terminal.app 启动的 shell 是什么类型呢?一般来讲,应该是 interactive, non-login shell,但实际上倒是 interactive, login shell,至于为何这样就不深究了。下面的测试代码能够证实:app

1
2 
[[ -o login ]] && echo 'yes' || echo 'no' [[ -o interactive ]] && echo 'yes' || echo 'no' 

因此,打开 iTerm.app 或者 Terminal.app 启动的 shell 会读取上述1-5中存在的全部文件,若是其中多个文件均对 PATH 环境变量做过设置,那么最终呈现的 PATH 环境变量就会比较复杂,部分路径重复也就不足为奇了。查看 /etc/zshenv,会发现调用的是/usr/libexec/path_helper,而它加载的正是系统路径,而且将系统路径放在最前。若是接下来用户在 $ZDOTDIR 中的文件中加载了本身设置的路径并置于最前,再接下来再加载的 /etc/zprofile、/etc/zshrc 可能还会调用/usr/libexec/path_helper,又形成了系统路径从新被放到最前面,造成了奇葩的 PATH 环境变量系统路径、自设路径、系统路径交错的现象。ssh

了解了这么多,解决方法也很简单,那就是上述1-5中仅让必要的文件涉及 PATH 环境变量。好比在 /etc/zshenv 中经过调用/usr/libexec/path_helper设置系统路径,$ZDOTDIR/.zshenv 中将自设路径放在最前,其他文件均不涉及 PATH 环境变量设置。测试

 

原文地址:https://www.jmlog.com/set-path-in-zsh-on-mac-os-x/spa

相关文章
相关标签/搜索