zoukankan      html  css  js  c++  java
  • 【转】Mac OS X 中 Zsh 下 PATH 环境变量的正确设置

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

    zsh 启动过程中会依次读取以下文件:

    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(非交互)方式执行。

    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。

    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,至于为什么这样就不深究了。下面的测试代码可以证明:

    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 环境变量系统路径、自设路径、系统路径交错的现象。

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

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

  • 相关阅读:
    easyui datagrid 遇到的坑 cannot read property ·· pageNum bug and so on
    原生js上传图片时的预览
    yield的理解
    js时间格式化
    js 实现复制粘贴时注意方法中需要两次点击实现的bug
    jquery 页面分页的实现
    easyui dialog 表单提交,弹框初始化赋值,dialog实现
    a标签(普通标签如span)没有disabled属性 ,怎样利用js实现该属性
    js之数据类型(对象类型——构造器对象——数组2)
    js之数据类型(对象类型——构造器对象——数组1)
  • 原文地址:https://www.cnblogs.com/sdlypyzq/p/5001037.html
Copyright © 2011-2022 走看看