PATH
环境变量中。我知道这可以通过编辑.bashrc
(例如)来完成,但尚不清楚如何做到这一点。这种方式: prettyprint-override“>
export PATH=~/opt/bin:$PATH
还是这个?
export PATH=$PATH:~/opt/bin
#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
是特殊语法,并且export
和PATH=~/opt/bin:$PATH
甚至都做正确的事情。在其他Bourne / POSIX样式的外壳程序中,例如破折号(在许多系统上为export PATH=~/opt/bin:$PATH
),/bin/sh
被解析为普通命令,这意味着两个区别:export
仅在单词的开头进行解析,除在赋值中外(有关详细信息,请参见如何添加Unix将通过哪个命令找到主目录路径?以了解详细信息);或~
。因此,在破折号之类的外壳中,
$PATH
将PATH
设置为文字字符串\[*?
,后跟export PATH=~/opt/bin:$PATH
的值,直到第一个空格。PATH
(裸分配)不会需要引号并做正确的事情。如果要在可移植脚本中使用~/opt/bin/:
,则需要编写PATH
或PATH=~/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 楼
一段时间以来,我一直使用两个函数pathadd
和pathrm
来帮助在路径中添加元素,而无需担心重复。 在几乎每种情况下,如果您要添加到路径,那么您可能想覆盖路径中已有的任何内容,这就是为什么我选择默认为默认。
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
评论
printf'\ nPATH = $ PATH:“添加路径” \ nexport PATH \ n'>>〜/ .bashrcUnix 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-sathe/pathin