从 PATH 变量中删除重复的条目

从 PATH 变量中删除重复的条目

我经常修改 .bashrc 然后执行 source 命令。但是,当 export PATH="~/bin:~/perl5/bin:$PATH"我的文件中含有类似内容时,PATH每次执行 source 命令时,环境变量都会增大。

例如,第一次调用 .bashrc 时,PATH变量由 组成~/bin:~/perl5/bin:/usr/bin:/bin

第二次它由组成~/bin:~/perl5/bin:~/bin:~/perl5/bin:/usr/bin:/bin

第三次则由 组成~/bin:~/perl5/bin:~/bin:~/perl5/bin:~/bin:~/perl5/bin:/usr/bin:/bin

有没有一种简单的方法可以让它只添加 PATH 中尚不存在的内容?

答案1

使用大多数发行版中提供的 pathmunge() 函数/etc/profile

pathmunge () {
if ! echo $PATH | /bin/egrep -q "(^|:)$1($|:)" ; then
   if [ "$2" = "after" ] ; then
      PATH=$PATH:$1
   else
      PATH=$1:$PATH
   fi
fi
}

编辑:对于zsh用户来说,typeset -U <variable_name>将对路径条目进行重复数据删除。

答案2

我遇到了这个问题,所以我使用了堆栈溢出问题。以下是我用来对已设置的实际 PATH 变量进行重复数据删除的方法,因为我不想修改基本脚本。

    tmppath=(${PATH// /@})
    array=(${tmppath//:/ })
    for i in "${array[@]//@/ }"
    do
        if ! [[ $PATH_NEW =~ "$i" ]]; then
            PATH_NEW="${PATH_NEW}$i:";
        fi
    done;
    PATH="${PATH_NEW%:}"
    export PATH
    unset PATH_NEW

您可以随时对此进行进一步优化,但我在原始代码中加入了额外的代码来显示正在发生的事情,以确保它正确设置了变量。另外需要注意的是,我执行以下操作

  1. 用 @ 字符替换任何 SPACE 字符
  2. 分割数组
  3. 循环遍历数组
  4. 用空格替换元素字符串中的任何 @ 字符

这是为了确保我可以处理带有空格的目录(具有 Active Directory 用户名的 Samba 主目录可以有空格!)

答案3

明确设置你的路径。

答案4

我想到两种不同的方法可以解决这个问题。第一种方法是,在 .bashrc 的开头添加一行明确设置基本 PATH,这样每次执行 source 命令时,都会在添加其他目录之前将其重置为基本 PATH。

例如,添加:

# Reset the PATH to prevent duplication and to make sure that we include
# everything we want.
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

或者,您可以在将项目添加到路径之前检查该项目。为此,您可以使用类似以下内容:

if ! [[ $PATH =~ '~/perl5/bin' ]]
then
    PATH="~/perl5/bin:$PATH"
fi

但是,如果添加大量条目,后者往往会变得有些重复,因此我倾向于坚持使用前者。如果您想使用这种方法并计划添加大量条目,编写一个 bash 函数来处理它将是明智之举。

注意:第二个选项可能仅在现代版本的 bash 中有效。正则表达式支持不是 Bourne Shell (/bin/sh) 功能,并且可能不存在于其他 shell 中。此外,在某些最新版本的 bash 上,可能不需要使用引号,甚至可能导致问题。

相关内容