我想知道必须将新路径添加到PATH环境变量中。我知道这可以通过编辑.bashrc(例如)来完成,但尚不清楚如何做到这一点。

这种方式: prettyprint-override“> export PATH=~/opt/bin:$PATH

还是这个?



export PATH=$PATH:~/opt/bin


评论

printf'\ nPATH = $ PATH:“添加路径” \ nexport PATH \ n'>>〜/ .bashrc

Unix shell函数,用于将目录添加到PATH

如果已经添加了一些路径,例如PATH = $ PATH:$ HOME / .local / bin:$ HOME / bin,另一个可以通过用:分隔来添加: PATH = $ PATH:$ HOME / .local / bin:$ HOME / bin:/ home / ec2-user / pear / bin。

这些答案适用于所有Linux版本吗?

写了一个小工具来帮助解决这个问题。 github.com/aalok-sa​​the/pathin

#1 楼

简单的东西

PATH=$PATH:~/opt/bin




PATH=~/opt/bin:$PATH


,具体取决于是否要在末尾添加~/opt/bin(如果在多个目录中有相同名称的程序,则在所有其他目录之后进行搜索)或在开头(在所有其他目录之前进行搜索)进行搜索。

可以在以下位置添加多个条目同一时间。 PATH=$PATH:~/opt/bin:~/opt/node/bin或订购工作上的变化都很好。不要将export放在该行的开头,因为它会带来更多的复杂性(请参见下文“除bash之外的其他shell注释”)。

如果您的PATH由许多不同的组件组成,则可能最终出现重复的条目。请参阅如何添加Unix可以通过以下命令发现的主目录路径?并使用awk命令删除重复的$ PATH条目,以避免添加重复或将其删除。

有些发行版会自动将~/bin放入PATH中(如果存在的话)。

放入

将行修改为PATH~/.profile(如果您有的话)。

请注意,任何程序都不会读取~/.bash_profile,而~/.bash_rc是bash交互式实例的配置文件。您不应在~/.bashrc中定义环境变量。定义环境变量(例如~/.bashrc)的正确位置是PATH(如果您不关心bash以外的其他shell,则可以选择~/.profile)。请参阅它们和有什么区别?

不要将它们放在~/.bash_profile/etc/environment中:这些不是shell文件,您不能在其中使用类似~/.pam_environment的替换。在这些文件中,您只能覆盖变量,而不能将其添加。

某些系统脚本中可能存在的并发症

如果变量已经在环境中,则不需要$PATH:变量值的任何变化都反映在环境中。¹export几乎总是在环境中;所有的UNIX系统都非常早地设置了它(实际上通常是在第一个过程中)。

在登录时,您可以依靠PATH已经存在于环境中,并且已经包含一些系统目录。如果编写的脚本可能在设置某种虚拟环境时提前执行,则可能需要确保PATH为非空并已导出:如果PATH仍未设置,则类似PATH的操作会将PATH=$PATH:/some/directory设置为PATH ,开头的空白部分表示当前目录(如:/some/directory)。

if [ -z "${PATH-}" ]; then export PATH=/usr/local/bin:/usr/bin:/bin; fi


关于bash以外的shell的注意事项

在bash中,ksh和zsh,.:/some/directory是特殊语法,并且exportPATH=~/opt/bin:$PATH甚至都做正确的事情。在其他Bourne / POSIX样式的外壳程序中,例如破折号(在许多系统上为export PATH=~/opt/bin:$PATH),/bin/sh被解析为普通命令,这意味着两个区别:




export仅在单词的开头进行解析,除在赋值中外(有关详细信息,请参见如何添加Unix将通过哪个命令找到主目录路径?以了解详细信息);或~

因此,在破折号之类的外壳中,$PATHPATH设置为文字字符串\[*?,后跟export PATH=~/opt/bin:$PATH的值,直到第一个空格。
PATH(裸分配)不会需要引号并做正确的事情。如果要在可移植脚本中使用~/opt/bin/:,则需要编写PATHPATH=~/opt/bin:$PATH(或export以便于移植到甚至不接受export PATH="$HOME/opt/bin:$PATH"且不进行代字扩展的Bourne外壳)。 />¹在Bourne外壳程序中并非如此(就像在实际的Bourne外壳程序中一样,而不是现代POSIX风格的外壳程序中),但是如今您不太可能遇到这样的旧外壳程序。

评论


仍然无法理解导出的复杂性。您能简化一下吗?

–priojeet priyom
19年7月12日在5:49

@priojeetpriyom简单的解释:您不需要导出。

–吉尔斯'所以-不再是邪恶的'
19年7月12日在8:30

谢谢您的回答,非常详细。您说“您不应该在〜/ .bashrc中定义环境变量”,但是不幸的是,我在系统上安装的修改路径的程序(FZF和Rust的货物)中有100%修改了.bashrc中的路径。我认为因为FZF也是用Rust编写的,所以它也遵循Rust的模式。

–icc97
19年7月30日在10:32



它也可以导出PATH ...

–therobyouknow
19/12/4在11:50

#2 楼

无论哪种方法都有效,但是它们却做不到相同的事情:从左到右检查PATH的元素。在第一个示例中,~/opt/bin中的可执行文件将优先于/usr/bin中安装的可执行文件,例如,可能不是您想要的文件。

尤其是从安全角度考虑,向前端添加路径很危险,因为如果某人可以获得对您的~/opt/bin的写访问权,那么他们可以在其中放一个不同的ls,然后您可能会在不注意的情况下使用它代替/bin/ls。现在,想象一下对于ssh或您的浏览器或选择都一样...(将。放在您的路径中也一样。)

评论


但是,如果要拥有自己的定制版本的ls,则需要将其放在/ bin之前的目录中。

– Barmar
2015年9月17日20:20在

或别名ls = myls

–沃尔丁纳
2015年9月18日,下午1:27

#3 楼

追加/保留的防弹方式
不使用
PATH=$PATH:~/opt/bin
PATH=~/opt/bin:$PATH

为什么?
涉及许多注意事项选择追加还是前置。其中许多都包含在其他答案中,因此在这里我将不再重复。
重要的一点是,即使系统脚本未使用此答案(我想知道为什么)* 1,
向PATH环境变量添加路径(例如~/opt/bin)的证明方法是
PATH="${PATH:+${PATH}:}~/opt/bin"

用于附加(而不是PATH="$PATH:~/opt/bin"

PATH="~/opt/bin${PATH:+:${PATH}}"

用于前置(而不是PATH="~/opt/bin:$PATH"
这样可以避免在$PATH最初为空时产生虚假的前导/尾部冒号,这可能会产生不良副作用,并且可能成为噩梦,难以捉摸(此答案简要地解决了awk -way的情况) 。
解释(来自Shell参数扩展):

${parameter:+word}

如果parameter为null或未设置,则不替换任何内容,否则替换word的扩展。 br />因此,${PATH:+${PATH}:}扩展为:

如果PATH为null或未设置,则什么也没有,

${PATH}:,如果PATH被设置。

注意:这是用于bash。
* 1我刚刚发现像`devtoolset-6 / enable`这样的脚本实际上使用了它,
$ cat /opt/rh/devtoolset-6/enable
# General environment variables
export PATH=/opt/rh/devtoolset-6/root/usr/bin${PATH:+:${PATH}}
...


#4 楼

我对问题2感到困惑(由于与问题无关,将其从问题中删除):


在不同的行上附加更多路径的可行方法是什么?
最初,我认为这可以解决问题:



export PATH=$PATH:~/opt/bin
export PATH=$PATH:~/opt/node/bin


但这不是因为第二个任务不仅只是追加了
~/opt/node/bin,还有以前分配的整个PATH

这是一种可能的解决方法:



export PATH=$PATH:~/opt/bin:~/opt/node/bin


/>,但出于可读性考虑,我宁愿为一个路径分配一个分配。


如果你说

PATH=~/opt/bin


所有这些都将放在您的PATH中。 PATH只是一个环境变量,如果要添加到PATH,则必须使用所需的内容来完全重建变量。就是说,您给出的问题2的示例正是您想要做的,除非我完全不知道问题的要点。

我在代码中同时使用了这两种形式。我有一个通用配置文件,安装在我使用的每台计算机上,看起来像这样,以适应可能丢失的目录:

评论


您对问题2的示例是正确的,它可以工作。我系统上另一个与PATH相关的问题使我感到困惑。抱歉

–保罗
2011-12-5在0:59

#5 楼

Linux使用$PATH环境变量确定可执行文件的搜索路径。要将目录/ data / myscripts添加到$PATH环境变量的开头,请使用以下命令:

PATH=/data/myscripts:$PATH


要将目录添加到路径的末尾,请使用以下命令:

PATH=$PATH:/data/myscripts


但是前面的命令是不够的,因为在脚本中设置环境变量时,该更改仅在脚本中有效。解决此限制的方法只有两种:


如果在脚本中,则导出环境变量,该变量在脚本调用的任何程序中均有效。请注意,它在调用脚本的程序中无效。
如果调用脚本的程序是通过包含而不是调用的方式进行的,则脚本中的任何环境更改都在调用程序中有效。可以使用点命令或源命令来完成这种包含。

示例:

$HOME/myscript.sh
source $HOME/myscript.sh


包含基本上将“被调用”脚本合并到“调用”脚本。就像C中的#include。因此它在“调用”脚本或程序中有效。但是,当然,它在调用程序调用的任何程序或脚本中均无效。为了使它在调用链中一直有效,您必须使用导出命令来遵循环境变量的设置。例如,bash shell程序通过以下方式合并文件.bash_profile的内容:包含。将以下两行放在.bash_profile中:

PATH=$PATH:/data/myscripts
export PATH


有效地将这两行代码放入bash程序中。因此,在bash中,$ PATH变量包含$HOME/myscript.sh,并且由于export语句,bash调用的所有程序都具有更改的$PATH变量。而且由于您从bash提示符运行的任何程序都被bash调用,因此对于从bash提示符运行的任何内容,新路径均有效。

最重要的是,要将新目录添加到路径,必须在外壳程序所包含的脚本内将目录追加或添加到$ PATH环境变量中,并且必须导出$PATH环境变量。

此处更多信息

#6 楼

一段时间以来,我一直使用两个函数pathaddpathrm来帮助在路径中添加元素,而无需担心重复。

在几乎每种情况下,如果您要添加到路径,那么您可能想覆盖路径中已有的任何内容,这就是为什么我选择默认为默认。

pathadd() {
    newelement=${1%/}
    if [ -d "" ] && ! echo $PATH | grep -E -q "(^|:)$newelement($|:)" ; then
        if [ "" = "after" ] ; then
            PATH="$PATH:$newelement"
        else
            PATH="$newelement:$PATH"
        fi
    fi
}

pathrm() {
    PATH="$(echo $PATH | sed -e "s;\(^\|:\)${1%/}\(:\|$\);;g" -e 's;^:\|:$;;g' -e 's;::;:;g')"
}


将它们放在您想要更改PATH环境的任何脚本中,现在就可以执行。
pathadd "/foo/bar"
pathadd "/baz/bat" after
export PATH


如果路径已经存在,请确保不要添加。现在,如果要确保pathadd处于开始位置。

pathrm "/baz/bat"
pathadd "/baz/bat"
export PATH


现在,如果已经在路径中而没有加倍,那么任何路径都可以移到前面。 >

评论


相关且更简洁的方法来检查PATH中是否存在目录:unix.stackexchange.com/a/32054/135943

–通配符
19年7月26日在19:03

#7 楼

我不能说其他发行版,但是Ubuntu有一个文件/ etc / environment,这是所有用户的默认搜索路径。由于我的计算机仅由我使用,因此除非在脚本中添加了临时添加内容,否则我会将所需的所有目录都放在该目录中。

#8 楼

要将新路径添加到PATH环境变量,请执行以下操作:

export PATH=$PATH:/new-path/


要将此更改应用于您打开的每个外壳,请将其添加到该外壳将作为源当它被调用时。在不同的shell中可以是:


Bash Shell:〜/ .bash_profile,〜/ .bashrc或profile
已知的Shell:〜/ .kshrc或.profile
Z Shell:〜/ .zshrc或.zprofile

例如

# export PATH=$PATH:/root/learning/bin/
# source ~/.bashrc
# echo $PATH


您可以在上面的输出中看到提供的路径。

#9 楼

在某些情况下,使用PATH=/a/b:$PATH可能会被认为是向PATH添加路径的“不正确”方法:


添加实际上不是目录的路径。
添加以相同的形式存在于PATH中的路径。
添加相对路径(因为搜索到的实际目录会随着更改当前工作目录而改变)。
以不同的形式添加已存在于PATH中的路径(即,由于使用符号链接或..而导致的别名)。
如果要避免执行4,当打算覆盖PATH中的其他条目时,请勿将路径移至PATH的前面。

此功能(仅限Bash)在上述情况下(除了例外,请参阅下文)在“做正确的事”,返回错误代码并为人类打印好消息。错误代码和消息可以在不需要时被禁用。

prepath() {
    local usage="\
Usage: prepath [-f] [-n] [-q] DIR
  -f Force dir to front of path even if already in path
  -n Nonexistent dirs do not return error status
  -q Quiet mode"

    local tofront=false errcode=1 qecho=echo
    while true; do case "" in
        -f)     tofront=true;       shift;;
        -n)     errcode=0;          shift;;
        -q)     qecho=':';          shift;;
        *)      break;;
    esac; done
    # Bad params always produce message and error code
    [[ -z  ]] && { echo 1>&2 "$usage"; return 1; }

    [[ -d  ]] || { $qecho 1>&2 " is not a directory."; return $errcode; }
    dir="$(command cd ""; pwd -P)"
    if [[ :$PATH: =~ :$dir: ]]; then
        $tofront || { $qecho 1>&2 "$dir already in path."; return 0; }
        PATH="${PATH#$dir:}"        # remove if at start
        PATH="${PATH%:$dir}"        # remove if at end
        PATH="${PATH//:$dir:/:}"    # remove if in middle
    fi
    PATH="$dir:$PATH"
}


例外是该函数无法规范化通过其他方式添加到PATH的路径,因此如果路径的非规范别名位于PATH中,则将添加重复项。尝试规范化PATH中已经存在的路径是一个简单的命题,因为相对路径在传递给prepath时具有明显的含义,但是当已经在路径中时,您不知道添加该目录时的当前工作目录是什么。

评论


关于相对路径:使用“ -r”开关怎么样?它将在不首先使它成为绝对路径的情况下添加该路径,并且还会在添加它之前将其寻找为绝对路径?如果这是脚本,则可以在其他shell中使用它。将其作为功能有什么好处?漂亮的代码!

–hoijui
19年6月10日在6:23

@hoijui它必须是一个函数,因为它正在修改当前环境。如果是脚本,它将修改运行该脚本的子进程的环境,并且当脚本退出时,您将拥有与以前相同的$ PATH。至于-r,不,我认为$ PATH中的相对路径太不可靠且很奇怪(每次cd时,您的路径都会改变),以至于不想在通用工具中支持类似的东西。

– cjs
19年6月10日在10:15

#10 楼

对我(在Mac OS X 10.9.5上)而言,将路径名(例如/mypathname)添加到文件/etc/paths效果很好。

在编辑之前,echo $PATH返回:

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


编辑/etc/paths并重新启动外壳后,$ PATH变量将附加/pathname。实际上,echo $PATH返回:

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/mypathname


发生的事情是/mypathname已附加到$PATH变量中。

评论


将文件添加到/etc/paths.d目录比编辑/ etc / paths文件本身更好。

– rbrewer
2016年9月7日20:50在

#11 楼

这是我的解决方案:

PATH=$(echo -n $PATH | awk -v RS=: -v ORS=: '!x[q4312078q]++' | sed "s/\(.*\).\{1\}//")


一个很好的简单内衬,不会留下拖尾:

评论


-bash:awk:没有这样的文件或目录-bash:sed:没有这样的文件或目录

– davidcondrey
16年11月21日在19:18

@davidcondrey-awk和sed是非常常见的外部命令。该答案提供了一种纯方式来实现此目的,因此即使在没有awk和/或sed(或它们各自的目录不在路径中的情况下)也可以使用该答案。

– sancho.s ReinstateMonicaCellio
18年1月19日在9:45