【问题标题】:virtualenv directory shifted to the end of $PATH when running zsh -l -c 'echo "__${PATH}__"'运行 zsh -l -c 'echo "__${PATH}__"' 时,virtualenv 目录移动到 $PATH 的末尾
【发布时间】:2014-08-27 04:28:53
【问题描述】:

为什么virtualenv路径在最后一条命令中移到了末尾?

Last login: Tue Aug 26 19:14:49 on ttys000
➜  ~  echo $PATH
/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin
➜  ~  zsh -l -c 'echo "__${PATH}__"'
__/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin__
➜  ~  . ./venvs/py_venv/bin/activate
(py_venv)➜  ~  echo $PATH
/Users/aj/venvs/py_venv/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin
(py_venv)➜  ~  zsh -l -c 'echo "__${PATH}__"'
__/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin:/Users/aj/venvs/py_venv/bin__
(py_venv)➜  ~

编辑:

进一步调查似乎表明它与单引号与双引号有关。仍然不确定为什么:

(py_venv)➜  ~  zsh -l -c "echo $PATH"
/Users/aj/venvs/py_venv/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin
(py_venv)➜  ~  zsh -l -c 'echo $PATH'
/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin:/Users/aj/venvs/py_venv/bin

【问题讨论】:

    标签: python macos shell virtualenv zsh


    【解决方案1】:

    在我的 (Ubuntu) zsh 环境中,我没有看到行为差异,但我怀疑在你的情况下(可能与特定于 OS 的某些东西有关X) 这可能与 双引号 允许完全替换,而 单引号 不允许这一事实有关。

    例如,如果您运行echo '$PATH',它将按字面意思输出$PATH,而echo "$PATH" 会将环境变量的值替换为 echo 命令并输出完整路径。

    Further reading on zsh quoting

    编辑:

    我尝试了您的确切 zsh 命令的一些变体,并且可以重现类似的东西,尽管我最终没有输出而不是转移到最后:

     (venv_test) ~  zsh -l -c 'echo "__$PATH__"'
    __
     (venv_test) ~  zsh -l -c 'echo __$PATH__' 
    __
     (venv_test) ~  zsh -l -c "echo __$PATH__"
    __
     (venv_test) ~  zsh -l -c "echo __${PATH}__"
    __/home/khampson/virtualenvs/venv_test/bin:/home/khampson/bin__
    

    尝试切换到 双引号,并在 env var 周围使用 花括号(我怀疑结尾的下划线会被视为 env var 名称的一部分)。 p>

    【讨论】:

    • 这是问题的一部分。 zsh -l -c "echo $PATH" 正在执行完全替换,因此不需要的字符串 echo /Users/aj/venvs/py_venv/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin 被传递给 -c。而对于zsh -l -c 'echo $PATH',所需的字符串echo $PATH 被传递给-c。 venv 目录移到末尾的原因是因为一个恼人的 Mac OS X 怪癖,我将在下面添加一个答案。
    【解决方案2】:

    来自 zsh 手册页:

    STARTUP/SHUTDOWN FILES
           Commands are first read from /etc/zshenv; this cannot be overridden....
    

    那么让我们看看默认情况下 Mac OS X 有什么:

    ➜  ~  cat /etc/zshenv
    # system-wide environment settings for zsh(1)
    if [ -x /usr/libexec/path_helper ]; then
        eval `/usr/libexec/path_helper -s`
    fi
    

    好的,/usr/libexec/path_helper 是什么?

    ➜  ~  man path_helper
    DESCRIPTION
         The path_helper utility reads the contents of the files in the directories /etc/paths.d and /etc/manpaths.d and appends their contents to the PATH and MANPATH environment variables respectively.
    

    那么如果path_helper追加,那为什么venv目录会被推到最后呢?答案是它不附加,它预先设置并且文档不正确。它似乎也在做一些重复数据删除:

    (py_venv)➜  ~  echo $PATH
    /Users/aj/venvs/py_venv/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin
    (py_venv)➜  ~  /usr/libexec/path_helper -s
    PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin:/Users/aj/venvs/py_venv/bin"; export PATH;
    (py_venv)➜  ~  PATH="" /usr/libexec/path_helper -s
    PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin"; export PATH;
    (py_venv)➜  ~  PATH="/foo/bar" /usr/libexec/path_helper -s
    PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin:/foo/bar"; export PATH;
    (py_venv)➜  ~  PATH="/foo/bar:/usr/bin:/usr/local/bin" /usr/libexec/path_helper -s
    PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin:/foo/bar"; export PATH;
    (py_venv)➜  ~
    

    【讨论】:

      猜你喜欢
      • 2020-01-21
      • 1970-01-01
      • 2010-12-02
      • 1970-01-01
      • 1970-01-01
      • 2018-07-20
      • 2017-11-09
      • 1970-01-01
      • 2015-06-18
      相关资源
      最近更新 更多