从$ PATH变量中删除冗余路径


125

我已经在$ PATH变量中定义了6次相同的路径。

我没有注销来检查它是否有效。

如何删除重复项?

$ PATH变量如下所示:

echo $PATH

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/flacs/Programmes/USFOS/bin:/home/flacs/Programmes/USFOS/bin:/home/flacs/Programmes/USFOS/bin:/home/flacs/Programmes/USFOS/bin:/home/flacs/Programmes/USFOS/bin:/home/flacs/Programmes/USFOS/bin

我如何将其重置为

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

您在哪里定义了6次?在哪些文件中?
hovanessyan 2012年


Answers:


122

您只需执行:

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

如果您想永久更改,请将其添加到任何.bashrc,bash.bashrc,/ etc / profile-适用于您的系统和用户的需要。

注意:这是针对Linux的。对于新的编码器,我们将予以明确。(`,')不要尝试SET =这些。


是的,我将它们永久设置在bash.bashrc中。那么命令应该像这样吗? echo 'export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games' >> ~/.bashrc
查尔斯·亨德利(Charles hendry)2012年

事实是,取决于您的操作系统,会执行一系列配置。您需要确保PATH变量以后不会被覆盖。(对于一个用户)最简单的方法是在用户的.bashrc文件中覆盖它,该文件通常位于他的主目录中。
hovanessyan

1
您的命令将PATH设置为-$ PATH(PATH的当前值)+字符串/ usr / local / sbin:/ usr / local / bin:/ usr / sbin:/ usr / bin:/ sbin:/ bin:/ usr / gam‌es。如果只想使用字符串,请从命令中删除$ PATH +分号(:)。不管您使用echo还是手动编辑文件〜/ .bashrc都没有关系。
hovanessyan

bash.bashrc文件位于/ etc文件夹中。但是它不会显示$ PATH变量,所以我不确定在哪里进行编辑
charles hendry 2012年

在您的第一个注释中,您回显到〜/ .bashrc(引用:>>〜/ .bashrc),而不是/etc/bash.bashrc。如果要更改特定用户的PATH,请在/ home / <用户名> /。bashrc文件中对其进行编辑。/etc/bash.bashrc适用于所有用户。
hovanessyan

70

如果您使用的是Bash,如果/home/wrong/dir/要从PATH变量中删除目录,也可以执行以下操作:

PATH=`echo $PATH | sed -e 's/:\/home\/wrong\/dir\/$//'`

1
这对我很有用,因为我希望排除在/ etc / profile中添加的目录,但是没有对/ etc的写权限。谢谢:)
Samizdis 2014年

13
提示:您可以在sed表达式中使用不同的分隔符来避免\ /转义:PATH=$(echo $PATH | sed -e 's|:/home/wrong/dir|$||')
iNecas 2014年

4
当我想立即拥有新的PATH且不想退出当前终端时,此技巧很有用。但是,为避免混乱,应先尝试使用PATH生成命令(即echo $PATH | sed -e 's/:\/home\/wrong\/dir\/$//'),然后再将其分配给PATH。
biocyberman 2015年

2
当要删除的路径恰好是中的第一条路径时,此功能将无效$PATH。使用这个选项:PATH=$(echo :$PATH: | sed -e 's,:/home/wrong/dir:,:,g' -e 's/^://' -e 's/:$//')
罗宾·许

没有工作$ PATH=echo $ PATH | sed -e's /:\ / scratch \ / sjn \ / anaconda \ / bin \ / python \ / $ //'``删除/ scratch / sjn / anaconda / bin / python
Mona Jalal

13

Linux:从$ PATH变量中删除冗余路径

Linux From Scratch 在/ etc / profile中具有此功能

# Functions to help us manage paths.  Second argument is the name of the
# path variable to be modified (default: PATH)
pathremove () {
        local IFS=':'
        local NEWPATH
        local DIR
        local PATHVARIABLE=${2:-PATH}
        for DIR in ${!PATHVARIABLE} ; do
                if [ "$DIR" != "$1" ] ; then
                  NEWPATH=${NEWPATH:+$NEWPATH:}$DIR
                fi
        done
        export $PATHVARIABLE="$NEWPATH"
}

这些功能旨在与这些功能一起使用,以添加到路径中,这样就不会多余地执行此操作:

pathprepend () {
        pathremove $1 $2
        local PATHVARIABLE=${2:-PATH}
        export $PATHVARIABLE="$1${!PATHVARIABLE:+:${!PATHVARIABLE}}"
}

pathappend () {
        pathremove $1 $2
        local PATHVARIABLE=${2:-PATH}
        export $PATHVARIABLE="${!PATHVARIABLE:+${!PATHVARIABLE}:}$1"
}

简单的用法是只提供pathremove要删除的目录路径-但请记住,它必须完全匹配:

$ pathremove /home/username/anaconda3/bin

这将从路径中删除该目录的每个实例。

如果您要在路径中使用目录,但没有冗余,则可以使用其他功能之一,例如-针对您的特定情况:

$ pathprepend /usr/local/sbin
$ pathappend /usr/local/bin
$ pathappend /usr/sbin
$ pathappend /usr/bin
$ pathappend /sbin
$ pathappend /bin
$ pathappend /usr/games

但是,除非考虑到可读性,否则此时最好还是这样做:

$ export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

以上内容在人类已知的所有外壳中都可以工作吗?

我会假设上面的工作中shdash以及bash至少。得知它在ksh中不起作用csh,我会感到惊讶fish', or。我怀疑它是否可以在Windows命令shell或Powershell中工作。

如果您拥有Python,则以下类型的命令应该执行直接要求的操作(即,删除冗余路径):

$ PATH=$( python -c "
import os
path = os.environ['PATH'].split(':')
print(':'.join(sorted(set(path), key=path.index)))
" )

单线(避免多行问题):

$ PATH=$( python -c "import os; path = os.environ['PATH'].split(':'); print(':'.join(sorted(set(path), key=path.index)))" )

上面删除了以后的冗余路径。要删除早期的冗余路径,请使用反向列表的索引并再次对其进行反向:

$ PATH=$( python -c "
import os
path = os.environ['PATH'].split(':')[::-1]
print(':'.join(sorted(set(path), key=path.index, reverse=True)))
" )

+1。pathremove()是否可以在所有外壳样式(如csh,ksh,bash等)中使用?顺便说一句,我在RHEL上的/ etc / profile没有partremove(),而只有pathmunge()。
塔加尔18/10/21

1
@Tagar我不保证与所有其他Shell的兼容性。我建议在正在使用的任何外壳上对其进行测试,如果它不适用于您的外壳,则可以在安装了Python的情况下使用它-我在答案中添加了一些Python来描述如何使用。
亚伦·霍尔

如果我正确阅读了“ 3.5.3 Shell参数扩展”,${!PATHVARIABLE}则是一种变量间接访问,但是我不确定它在这里如何工作。你能解释一下吗?
loxaxs

@loxaxs这是那些bash函数中的局部变量,使用local内置声明(只能在函数内部使用。)如果还有其他问题,您可能应该在网站上提出一个新问题(在首先搜索以确保您没有创建完全相同的副本...)。
亚伦·霍尔

这是一个非常有趣的答案,谢谢您的写作!但是,清理混乱的PATH变量的原始问题似乎并没有得到很好的解决(我承认,尽管如此,当使用此功能时,开始时并不会陷入混乱的PATH)。
克里斯汀·赫伦茨

9

这是清除PATH的一行代码

  • 它不会干扰PATH的顺序,只删除重复项
  • 对待:并优雅地清空PATH
  • 没有使用特殊字符,因此不需要转义
  • 使用/bin/awk它即使在PATH中断时也能正常工作

    export PATH="$(echo "$PATH" |/bin/awk 'BEGIN{RS=":";}
    {sub(sprintf("%c$",10),"");if(A[$0]){}else{A[$0]=1;
    printf(((NR==1)?"":":")$0)}}')";

1
有人测试过吗?是安全的?
Joe RR

2
如果您没有安装awk,它将清理您的路径,建议您在使用echo $ PATH之前将路径复制到txt文件中
Jose Pita

对我不起作用...我已经安装了awk,但是某些重复项没有被删除。
Christian Herenz

3
  1. 只是 echo $PATH
  2. 将详细信息复制到文本编辑器中
  3. 删除不需要的条目
  4. PATH= # pass new list of entries

2

如果您只想删除任何重复的路径,那么我会使用一段时间后写的脚本,因为我在使用多个perl5 / bin路径时遇到了麻烦:

#!/bin/bash
#
# path-cleanup
#
# This must be run as "source path-cleanup" or ". path-cleanup"
# so the current shell gets the changes.

pathlist=`echo $PATH | sed 's/:/\n/g' | uniq`

# echo "Starting PATH: $PATH"
# echo "pathlist: $pathlist"
unset PATH
# echo "After unset, PATH: $PATH"
for dir in $pathlist
do
    if test -d $dir ; then
        if test -z $PATH; then
            PATH=$dir
        else
            PATH=$PATH:$dir
        fi
    fi
done
export PATH
# echo "After loop, PATH: $PATH"

然后将其放在我的〜/ .profile中。由于我几乎只使用BASH,因此我没有在其他Shell中尝试过它。


1
+1为解决方案。顺便说一句,它只会删除重复的路径,如果它们在一个接一个的列表中。您可以进行更改|uniq|sort|uniq解决此问题,但这将更改路径中所有目录的顺序,我认为这不是理想的副作用。
塔加

1

假设您的外壳是Bash,则可以使用以下命令设置路径

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

但是就像Levon在另一个答案中所说的那样,一旦终止Shell,更改将消失。你可能想设置你PATH~/.bash_profile~/.bashrc



0

没有标准工具可以“编辑”值$PATH(即“仅在尚不存在时添加文件夹”或“删除此文件夹”)。

要检查下次登录时的路径,请使用telnet localhost(或telnet 127.0.0.1)。然后它将询问您的用户名和密码。

这为您提供了一个新的登录shell(即一个全新的,不继承当前环境中的任何内容)。

您可以检查$PATHthere 的值并编辑rc文件,直到正确为止。这对于查看对重要文件进行更改后是否可以再次登录也很有用。


无需输入用户名/密码,只需输入即可/bin/bash -i。麻烦少很多。
Ed Heal 2012年

0

您如何将这些重复的路径添加到PATH变量中?您必须已经编辑了其中一个.文件。(.tcshrc.bashrc等等,具体取决于您的特定系统/外壳)。解决该问题的方法是再次编辑文件并删除重复的路径。

如果您没有编辑任何文件,则必须以交互方式修改PATH。在这种情况下,更改不会“粘滞”,即,如果您打开另一个外壳,或者注销并重新登录,更改将自动消失。

请注意,也有一些系统范围的配置文件,但是您不太可能修改它们,因此很可能会在个人主目录中更改文件(如果您希望在确定一组路径后使这些更改永久生效)


0

对于一个简单的复制粘贴模板,我使用以下Perl代码段:

PATH=`echo $PATH | perl -pe s:/path/to/be/excluded::`

这样,您就不必为替代运算符转义斜线。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.