微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

PATH中的重复目录

如何解决PATH中的重复目录

我刚刚按照this教程通过brew将我的mac(2015)重置为Catalina 10.15.6,并安装了python3。我的工作正常,在〜/中创建了一个.zshrc文件,并将brew的位置添加到PATH中。昨晚,我正在尝试在.zshrc文件修改我的PS1变量(该文件中也包含以下行:export PATH='/usr/local/opt/python/libexec/bin:{PATH}。使用nano .zshrc和{{1 }}我回响了我的PATH,我明白了:source .zshrc(您明白了)。

我认为这是因为我在一个会话中跑了/usr/local/opt/python/libexec/bin:/usr/local/bin:/usr/bin/bin:/usr/sbin:/sbin:/usr/local/opt/python/libexec/bin:/usr/local/bin:/usr/bin/bin:/usr/sbin:/sbin:/usr/local/opt/python/libexec/bin:/usr/local/bin:/usr/bin/bin:/usr/sbin:/sbin:/usr/local/opt/python/libexec/bin:/usr/local/bin:/usr/bin/bin:/usr/sbin:/sbin:/usr/local/opt/python/libexec/bin:/usr/local/bin:/usr/bin/bin:/usr/sbin:/sbin:/usr/local/opt/python/libexec/bin:/usr/local/bin:/usr/bin/bin:/usr/sbin:/sbin次了吗?任何人都可以解释/指导我每次都不要在.zshrc文件中工作时都遇到此问题。

谢谢!

解决方法

通常的解决方法是在添加之前进行检查。这适用于POSIX sh,但我想它也应该在Zsh中工作。

for d in /sbin /usr/sbin /usr/bin/bin /usr/local/bin /usr/local/opt/python/libexec/bin
do
    case :$PATH: in
     *:"$d":*) continue ;;
    esac
    PATH=$d${PATH+":$PATH"}
done

实际上,作为系统范围环境配置的一部分,当您启动计算机时,除最后一个以外的所有内容可能已经在PATH上。

, 当您只运行一个新的交互式子shell时,也会再次处理

.zshrc。通常,您可以通过一些控制变量来防止变量(例如PATH)的重复扩展。我的解决方案是这样的:

_SH_ONCE_VERSION=0 
: S{SH_ONCE:=} # Just in case you run with set -u enabled.
export SH_ONCE # It is important to make this one an environment variable
if [[ ${SH_ONCE:=0} != $_SH_ONCE_VERSION ]]
then
  # Do modifications here,which should not be done over and over
  PATH=/what/ever/you/want:$PATH  
  export some_var=$(some_long_running_command) # should not be done on every subshell
  ...
  # Guard against repeated inclusion:
  SH_ONCE=$_SH_ONCE_VERSION
fi

从此开始,第一次打开新外壳程序时,修改已完成,但是在每个子外壳程序上,它们都被跳过了。

现在,如果您在工作中对.zshrc的“受保护部分”进行了更改,会发生什么情况?您肯定希望至少一次应用您的更改,即使这样也可能会导致PATH更长。这是_SH_ONCE_VERSION起作用的地方。只需将其增加1:

    _SH_ONCE_VERSION=1

,新版本将再次被完全处理。

您应该考虑的是:使用这种策略,并且相对于PATH,如果将新目录添加到PATH的前面而不是末尾,则显然可行。

,

以三人发布的答案为基础,但是利用拥有zsh的事实,可以很容易地提出一个更可靠的解决方案,该解决方案可以捕获路径中任何位置的目录,

for dir_to_add in .... # List of directories to be added to the PATH,unless they are there already
do
  if (( ${path[(Ie)$dir_to_add]} ))
  then
    : # Directory already in PATH
  else
    PATH=$PATH:$dir_to_add # or: PATH=$dir_to_add:$PATH
  fi
done

请注意,标量PATH和数组path会自动保持同步。

说明:${A[(Ie)X}是X在数组A中的索引,如果X不在A中,则为0。

,

在zsh中,您可以将路径设置为仅允许唯一值:

typeset -U path PATH

-U选项可消除path数组和PATH变量中的重复项。 -U选项适用于所有常规数组,以及typeset -T所设置的“绑定参数”,例如PATH

演示:

typeset +U path PATH      # +U allows duplicates
PATH=/usr/sbin
echo 1 $PATH
#=>  1 /usr/sbin

PATH=$PATH:/usr/sbin
echo 2 $PATH
#=>  2 /usr/sbin:/usr/sbin

path+=(/usr/sbin /bin)
echo 3 $PATH
#=>  3 /usr/sbin:/usr/sbin:/usr/sbin:/bin


typeset -U path PATH      # no duplicates
echo 4 $PATH
#=>  4 /usr/sbin:/bin
echo 5 $path
#=>  5 /usr/sbin /bin

PATH=$PATH:/usr/sbin:/bin
echo 6 $PATH
#=>  6 /usr/sbin:/bin

path+=(/usr/sbin /bin)
echo 7 $path
#=>  7 /usr/sbin /bin

path+=(/usr/local/sbin /usr/local/bin)
print -l $path
#=>  /usr/sbin
#=>  /bin
#=>  /usr/local/sbin
#=>  /usr/local/bin

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。