如何从 $PATH 中删除重复的目录?

Mic*_*ael 3 linux bash path

在我的一些终端窗口中,我在PATH变量中有重复的条目;像这样:

PATH=/a/b:/c/d:/a/b:/c/d:/e/f:/a/b
Run Code Online (Sandbox Code Playgroud)

我想罪魁祸首是我的一些脚本中的这样一行:

PATH=/a/b:$PATH
Run Code Online (Sandbox Code Playgroud)

在采购这个和那个之后,这又PATH变得很长。这个问题:

是否有bash清理PATH和类似环境变量的命令?它应该是一个bash脚本,因为你不能执行一个实用程序并期望它改变调用 shell 的环境。

在上面的示例中,清理后的内容PATH应如下所示:

PATH=/a/b:/c/d:/e/f
Run Code Online (Sandbox Code Playgroud)

AFH*_*AFH 6

最好不要创建重复项,而不是事后尝试删除它们。使用我.bashrc在添加私有bin/目录时使用的技术可以轻松避免这种情况:

[ "${PATH#*$HOME/bin:}" == "$PATH" ] && export PATH="$HOME/bin:$PATH"
Run Code Online (Sandbox Code Playgroud)

我在更新的时候这样做了.bashrc,我想在不重新启动 shell 的情况下重新运行它。

如果要将目录添加到末尾,则$PATH需要使用前导冒号:

[ "${PATH#*:$HOME/bin}" == "$PATH" ] && export PATH="$PATH:$HOME/bin"
Run Code Online (Sandbox Code Playgroud)

您可以使用参数扩展来逐步执行PATH并删除重复项,但这会有点复杂,您需要决定应该保留哪个位置。类似的东西:-

OLDPATH="$PATH"; NEWPATH=""; colon=""
while [ "${OLDPATH#*:}" != "$OLDPATH" ]
do  entry="${OLDPATH%%:*}"; search=":${OLDPATH#*:}:"
    [ "${search#*:$entry:}" == "$search" ] && NEWPATH="$NEWPATH$colon$entry" && colon=:
    OLDPATH="${OLDPATH#*:}"
done
NEWPATH="$NEWPATH:$OLDPATH"
export PATH="$NEWPATH"
Run Code Online (Sandbox Code Playgroud)

在即时编写并进行测试之后,我应该删除了大多数错误,并且它应该是您需要做什么的充分指南。它会留下最后一次出现的任何重复项,如果您首先使用我的脚本来避免重复项,它们就会出现在该位置。在脚本中,它当然需要使用./source命令来调用。