Python 当运行zsh-l-c';“回声”__${PATH}';

Python 当运行zsh-l-c';“回声”__${PATH}';,python,macos,shell,virtualenv,zsh,Python,Macos,Shell,Virtualenv,Zsh,为什么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__ ➜ ~

为什么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
在我的(Ubuntu)zsh环境中,我看不到行为上的差异,但我怀疑在你的案例中(可能与OSX特定的东西有关),这可能与双引号允许完全替换有关,而单引号则不允许

例如,如果运行
echo“$PATH”
,它将直接输出
$PATH
,而
echo“$PATH”
将把环境变量的值替换为echo命令并输出完整路径

编辑:

我尝试了您的确切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__
尝试切换到环境变量周围带大括号的双引号(我怀疑后面的下划线会被视为环境变量名称的一部分)。

来自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\u 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)➜  ~

这是问题的一部分
zsh-l-c“echo$PATH”
正在进行完全替换,因此将不需要的字符串
echo/Users/aj/venvs/py\u venv/bin:/usr/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin
传递给-c。而使用
zsh-l-c'echo$PATH'
将所需字符串
echo$PATH
传递给-c。venv目录移到末尾的原因是因为一个恼人的MacOSX怪癖,我将在下面添加一个答案。