【问题标题】:How to handle duplicates in my PATH variable?如何处理我的 PATH 变量中的重复项?
【发布时间】:2017-10-29 03:27:34
【问题描述】:

我最近将此行添加到我的 .bashrc 文件中,以便我可以从命令行使用 java 编译器 javac(如果有不同,请使用 MobaXTerm)

export PATH=$PATH:"/cygdrive/c/Program Files/Java/jdk1.8.0_101/bin"

但我在$PATH 变量中看到多个重复项(请注意,添加换行符只是为了便于阅读)

/bin:
/drives/c/Users/Justin/DOCUME~1/MobaXterm/slash/bin:
/drives/c/WINDOWS:
/drives/c/WINDOWS/system32:
/cygdrive/c/ProgramFiles/Java/jdk1.8.0_101/bin:
/cygdrive/c/ProgramFiles/Java/jdk1.8.0_101/bin:
/cygdrive/c/ProgramFiles/Java/jdk1.8.0_101/bin

我添加到$PATH 的方式有问题吗?

【问题讨论】:

  • 你的意思是说export PATH=$PATH:"/cygdrive/c/ProgramFiles/Java/jdk1.8.0_101/bin"
  • 除非您重复获取 bashrc,否则该路径应该设置一次,除非它也在其他地方设置。

标签: bash shell path


【解决方案1】:

/etc/profile 中定义了一个名为 pathmunge 的函数:

pathmunge () {
    case ":${PATH}:" in
        *:"$1":*)
            ;;
        *)
            if [ "$2" = "after" ] ; then
                PATH=$PATH:$1
            else
                PATH=$1:$PATH
            fi
    esac
}

不幸的是,它在文件末尾也未设置。但是,只需删除未设置的行,您就可以在 .bashrc 文件中使用它。

【讨论】:

  • 我的系统上/etc/profile中没有pathmunge函数,我不建议这样修改系统文件。最好在自己的.bashrc.bash_profile 中定义pathmunge
  • @KeithThompson 它在 Redhat 上,文件顶部字面意思是 It's NOT a good idea to change this file unless you know what you are doing. It's much better to create a custom.sh shell script in /etc/profile.d/ to make custom changes to your environment, as this will prevent the need for merging in future updates.
  • @123: 当然可以,但是在你的主目录中制作自定义的 shell 脚本会更好。只有当您想让系统上的所有用户都可以使用这些东西时,在/etc/profile.d 中乱搞才有意义。 (现在很多系统只有一个用户,但这仍然是一个有用的区别。)
  • @KeithThompson 我不是在争论,我同意 /etc/profile 不应该改变。我引用了整个评论,但相关部分是It's NOT a good idea to change this file unless you know what you are doing.
【解决方案2】:

如果 PATH 由 .bashrc 调用的不同脚本操作,这通常是结果。

虽然 PATH 中的重复不是主要问题,但有两种方法可以使 PATH 中没有它们:

  1. 在添加前检查 PATH 中是否已存在目录
  2. 重复数据删除 PATH 作为 .bashrc 中的最后一步

添加前检查

javabin="/cygdrive/c/ProgramFiles/Java/jdk1.8.0_101/bin"
if ! [[ $PATH =~ "$javabin" ]]; then
  PATH="$PATH:$javabin"
fi

或者写一个函数:

add_to_path() {
    local dir re

    for dir; do
        re="(^$dir:|:$dir:|:$dir$)"
        if ! [[ $PATH =~ $re ]]; then
            PATH="$PATH:$dir"
        fi
    done
}

add_to_path "/cygdrive/c/ProgramFiles/Java/jdk1.8.0_101/bin"

Dedupe(我在 SO 上找到的最佳方法)

PATH="$(perl -e 'print join(":", grep { not $seen{$_}++ } split(/:/, $ENV{PATH}))')"

另请参阅 Unix 和 Linux / SuperUser StackExchange:

【讨论】:

  • <<< 不会在最后一条路径的末尾添加一个额外的换行符吗?
  • 好点,@123。我用我在这里找到的更优雅的东西替换了 awk 解决方案:unix.stackexchange.com/a/149054/201820
  • 是的,感谢您指出这一点。我有一个 bash 别名,它来自我的 .bashrc
猜你喜欢
  • 1970-01-01
  • 2017-02-21
  • 2016-06-18
  • 2014-06-08
  • 1970-01-01
  • 2017-02-12
  • 2012-02-17
  • 1970-01-01
  • 2016-07-05
相关资源
最近更新 更多