我通过Homebrew使用Mac OS X,iTerm2,zsh和Tmux。当我在iTerm2中启动终端会话时,全局PATH变量看起来仍然很好。但是当我打开一个Tmux会话时,PATH变量扩展了它已经包含的相同路径。我将在我的.zshrc中解决问题code snippet,但我仍然对PATH变量填充两次的原因感兴趣。
答案 0 :(得分:21)
这是因为您的.zshrc会针对每个新的zsh进程进行评估。因此,当你启动iTerm2时,会对你的$ PATH进行评估,然后当你启动获取修改后的$ PATH的tmux并将其传递给那里的zsh的新实例时,新的zsh进程再次评估.zshrc制作再次发生变化。
有几种方法可以阻止这种情况。
首先,为了明确防止tmux内部的shell发生,如果设置了$ TMUX,你可以跳过进行这些更改:
if [[ -z $TMUX ]]; then
PATH="$PATH:/foo"
fi
另一种选择是将.zshrc的那部分移动到.zprofile文件中。此文件仅由登录shell评估。但是,默认情况下,tmux会将新shell作为登录shell启动,因此您还需要通过在tmux配置中添加以下内容来阻止tmux执行此操作:
set -g default-command /bin/zsh
您可能需要调整zsh的路径。这会阻止tmux将zsh进程作为登录shell启动,因此tmux中的zsh不会查看.zprofile。
为了防止重复添加,您链接到的代码片段的另一个选项是将路径修改更改为:
typeset -aU path
path=( $path /foo )
这是有效的,因为zsh会自动将$ path变量设置为一个镜像$ PATH内容的数组。排版的-U选项修改该变量,以使条目唯一。
答案 1 :(得分:2)
我发现this GitHub thread非常有用。来自this comment的解决方案为我工作:
# /etc/zshenv
if [ -x /usr/libexec/path_helper ]; then
PATH="" # Add this line
eval `/usr/libexec/path_helper -s`
fi
通过这样做,您必须将PATH修改放在~/.zshrc
而不是~/.zprofile
。我也从帖子中尝试过this solution,但对我来说并不起作用。
答案 2 :(得分:0)
我的解决方案:
第 1 步:
在 .bashrc 或 .zshrc 中
ExtraPath="/foo/bar:$HOME/bin" # your customized path here, /foo/bar and $HOME/bin for instance
if ! [[ "$PATH" =~ "$ExtraPath" ]] ; then PATH="$ExtraPath:$PATH" ; fi # if the PATH does not contain your customized path, then insert yours, else do nothing.
第 2 步:
在 ~/.tmux.conf 中,添加
set -g default-command "${SHELL}"
在这种情况下,tmux 不会提供 /etc/profile,因此它不会与您的 PATH 混淆