Pao*_*olo 1174 bash path environment-variables bashrc
我想知道必须向PATH环境变量添加新路径的位置。我知道这可以通过编辑来完成.bashrc(例如),但不清楚如何做到这一点。
这边走:
export PATH=~/opt/bin:$PATH
Run Code Online (Sandbox Code Playgroud)
或这个?
export PATH=$PATH:~/opt/bin
Run Code Online (Sandbox Code Playgroud)
Gil*_*il' 1316
PATH=$PATH:~/opt/bin
Run Code Online (Sandbox Code Playgroud)
或者
PATH=~/opt/bin:$PATH
Run Code Online (Sandbox Code Playgroud)
取决于您是想~/opt/bin在末尾添加(在所有其他目录之后搜索,以防在多个目录中存在同名程序)还是在开头添加(在所有其他目录之前搜索)。
您可以同时添加多个条目。PATH=$PATH:~/opt/bin:~/opt/node/bin或订购工作的变化就好了。不要放在export行首,因为它有额外的复杂性(参见下面的“关于除 bash 之外的 shell 的注意事项”)。
如果您PATH由许多不同的组件构建,则最终可能会出现重复的条目。请参阅如何添加由 Unix 哪个命令发现的主目录路径?并使用 awk 命令删除重复的 $PATH 条目以避免添加重复项或删除它们。
~/bin顺便说一下,有些发行版会自动放入您的 PATH(如果存在)。
放线修改PATH的~/.profile,或者~/.bash_profile如果这就是你所拥有的。
注意,~/.bash_rc不是任何程序读取的,~/.bashrc是bash交互实例的配置文件。您不应在~/.bashrc. 定义环境变量的正确位置,例如PATHis ~/.profile(或者~/.bash_profile如果您不关心 bash 以外的 shell)。请参阅它们之间有什么区别,我应该使用哪一种?
不要把它放进去/etc/environment或~/.pam_environment:这些不是 shell 文件,你不能像$PATH那里那样使用替换。在这些文件中,您只能覆盖一个变量,而不能添加到它。
export如果变量已经在环境中,则不需要:变量值的任何变化都会反映在环境PATH中。¹ 几乎总是在环境中;所有的 Unix 系统很早就设置了它(实际上通常在第一个进程中)。
在登录时,您可以依赖PATH已经在环境中,并且已经包含一些系统目录。如果您正在编写可能在设置某种虚拟环境时提前执行的脚本,您可能需要确保它PATH是非空的并已导出:如果PATH仍未设置,则类似PATH=$PATH:/some/directory将设置PATH为:/some/directory,以及空组件开头表示当前目录(如.:/some/directory)。
if [ -z "${PATH-}" ]; then export PATH=/usr/local/bin:/usr/bin:/bin; fi
Run Code Online (Sandbox Code Playgroud)
在bash和ksh和zsh的,export是特殊的语法,都PATH=~/opt/bin:$PATH和export PATH=~/opt/bin:$PATH连做正确的事。在其他 Bourne/POSIX 样式的 shell 中,例如 dash(/bin/sh在许多系统上),export被解析为普通命令,这意味着两个不同之处:
~仅在单词的开头解析,除了在赋值中(请参阅如何添加由 Unix 哪个命令发现的主目录路径?有关详细信息);$PATH外面的双引号符如果PATH包含空格或\[*?。所以在像破折号这样的 shell 中,设置export PATH=~/opt/bin:$PATHPATH为文字字符串,~/opt/bin/:后跟PATH第一个空格的值。
PATH=~/opt/bin:$PATH(一个简单的任务)不需要引号并且做正确的事情。如果要export在可移植脚本中使用,则需要编写export PATH="$HOME/opt/bin:$PATH", or PATH=~/opt/bin:$PATH; export PATH(或PATH=$HOME/opt/bin:$PATH; export PATH为了可移植到甚至不接受export var=value也不进行波浪号扩展的 Bourne shell )。
¹这在 Bourne shell 中并非如此(如在实际的 Bourne shell 中,而不是现代 POSIX 样式的 shell),但是现在您极不可能遇到这样的旧 shell。
Ulr*_*arz 94
无论哪种方式都有效,但它们不做同样的事情:PATH从左到右检查的元素。在您的第一个示例中,可执行文件 in~/opt/bin将优先于已安装的可执行文件,例如 in /usr/bin,这可能是您想要的,也可能不是。
特别是,从安全的观点来看,这是很危险的路径添加到前面,因为如果有人能得到您的写入权限~/opt/bin,他们可以把,例如,不同ls在那里,你会那么很可能改用的/bin/ls没有注意到。现在想象相同的ssh或您的浏览器或选择......(将 . 放在您的路径中也是如此。)
san*_*lio 60
尝试不使用
PATH=$PATH:~/opt/bin
Run Code Online (Sandbox Code Playgroud)
或者
PATH=~/opt/bin:$PATH
Run Code Online (Sandbox Code Playgroud)
为什么? 选择附加还是前置需要考虑很多因素。其中许多在其他答案中都有涉及,因此我不会在此重复。
重要的一点是,即使系统脚本不使用这个(我不知道为什么)*1,~/opt/bin向 PATH 环境变量添加路径(例如,)的防弹方法是
PATH="${PATH:+${PATH}:}~/opt/bin"
Run Code Online (Sandbox Code Playgroud)
用于附加(而不是PATH="$PATH:~/opt/bin")和
PATH="~/opt/bin${PATH:+:${PATH}}"
Run Code Online (Sandbox Code Playgroud)
用于前置(而不是PATH="~/opt/bin:$PATH")
这避免了$PATH最初为空时的虚假前导/尾随冒号,这可能会产生不良副作用,并可能成为噩梦,难以找到(此答案简要介绍了这种情况awk)。
说明(来自Shell Parameter Expansion):
Run Code Online (Sandbox Code Playgroud)${parameter:+word}如果
parameter为 null 或未设置,则不替换任何内容,否则替换 的扩展word。
因此,${PATH:+${PATH}:}扩展为:
PATH为空或未设置,${PATH}:,如果PATH设置。注意:这是针对 bash 的。
$ cat /opt/rh/devtoolset-6/enable
# General environment variables
export PATH=/opt/rh/devtoolset-6/root/usr/bin${PATH:+:${PATH}}
...
Run Code Online (Sandbox Code Playgroud)
小智 40
我对问题 2 感到困惑(因为它是由于一个不相关的问题而从问题中删除的):
在不同行上附加更多路径的可行方法是什么?最初我认为这可以解决问题:
Run Code Online (Sandbox Code Playgroud)export PATH=$PATH:~/opt/bin export PATH=$PATH:~/opt/node/bin但这不是因为第二个分配不仅 append
~/opt/node/bin,而且还整个PATH先前分配。这是一个可能的解决方法:
Run Code Online (Sandbox Code Playgroud)export PATH=$PATH:~/opt/bin:~/opt/node/bin但为了可读性,我更愿意为一条路径分配一项任务。
如果你说
PATH=~/opt/bin
Run Code Online (Sandbox Code Playgroud)
这就是您的 PATH中的全部内容。PATH 只是一个环境变量,如果你想添加到 PATH,你必须用你想要的内容重建变量。也就是说,您对问题 2 给出的示例正是您想要做的,除非我完全没有抓住问题的要点。
我在我的代码中使用这两种形式。我有一个通用配置文件,我安装在我工作的每台机器上,看起来像这样,以适应可能丢失的目录:
export PATH=/opt/bin:/usr/local/bin:/usr/contrib/bin:/bin:/usr/bin:/usr/sbin:/usr/bin/X11
# add optional items to the path
for bindir in $HOME/local/bin $HOME/bin; do
if [ -d $bindir ]; then
PATH=$PATH:${bindir}
fi
done
Run Code Online (Sandbox Code Playgroud)
Ste*_*own 25
Linux 使用$PATH环境变量确定可执行搜索路径。要将目录 /data/myscripts 添加到$PATH环境变量的开头,请使用以下命令:
PATH=/data/myscripts:$PATH
Run Code Online (Sandbox Code Playgroud)
要将该目录添加到路径的末尾,请使用以下命令:
PATH=$PATH:/data/myscripts
Run Code Online (Sandbox Code Playgroud)
但是前面的方法还不够,因为当您在脚本中设置环境变量时,该更改仅在脚本内有效。只有两种方法可以解决此限制:
例子:
$HOME/myscript.sh
source $HOME/myscript.sh
Run Code Online (Sandbox Code Playgroud)
包含基本上将“被调用”脚本合并到“调用”脚本中。它就像 C 中的 #include。所以它在“调用”脚本或程序中是有效的。但是当然,它在调用程序调用的任何程序或脚本中都无效。为了使其在调用链中一直有效,您必须使用导出命令来遵循环境变量的设置。
例如,bash shell 程序通过包含来合并文件 .bash_profile 的内容。将以下 2 行放在 .bash_profile 中:
PATH=$PATH:/data/myscripts
export PATH
Run Code Online (Sandbox Code Playgroud)
有效地将这两行代码放在 bash 程序中。因此,在 bash 中, $PATH 变量包含$HOME/myscript.sh,并且由于导出语句,bash 调用的任何程序都具有更改的$PATH变量。并且因为您从 bash 提示符运行的任何程序都由 bash 调用,所以新路径对您从 bash 提示符运行的任何程序都有效。
最重要的是,要将新目录添加到路径中,您必须将目录附加到或预先添加到 shell 中包含的脚本中的 $PATH 环境变量,并且必须导出$PATH环境变量。
更多信息在这里
小智 22
一段时间以来,我一直使用两个函数pathadd,pathrm它们有助于将元素添加到路径中,而无需担心重复。
pathadd接受一个路径参数和一个可选after参数,如果提供该参数将附加到PATH否则它在它前面。
在几乎所有情况下,如果您要添加到路径中,那么您可能希望覆盖路径中已有的任何内容,这就是我选择默认添加的原因。
pathadd() {
newelement=${1%/}
if [ -d "$1" ] && ! echo $PATH | grep -E -q "(^|:)$newelement($|:)" ; then
if [ "$2" = "after" ] ; then
PATH="$PATH:$newelement"
else
PATH="$newelement:$PATH"
fi
fi
}
pathrm() {
PATH="$(echo $PATH | sed -e "s;\(^\|:\)${1%/}\(:\|\$\);\1\2;g" -e 's;^:\|:$;;g' -e 's;::;:;g')"
}
Run Code Online (Sandbox Code Playgroud)
将这些放在您希望更改 PATH 环境的任何脚本中,您现在可以这样做了。
pathadd "/foo/bar"
pathadd "/baz/bat" after
export PATH
Run Code Online (Sandbox Code Playgroud)
如果路径已经存在,您可以保证不会添加到路径中。如果您现在要确保/baz/bat是在开始。
pathrm "/baz/bat"
pathadd "/baz/bat"
export PATH
Run Code Online (Sandbox Code Playgroud)
现在任何路径都可以移动到前面,如果它已经在路径中而不会加倍。
小智 12
我不能说其他发行版,但 Ubuntu 有一个文件 /etc/environment,这是所有用户的默认搜索路径。由于我的计算机仅供我使用,因此我将我想要的任何目录放在我的路径中,除非它是我放在脚本中的临时添加。
Ami*_*4x7 10
要向PATH环境变量添加新路径:
export PATH=$PATH:/new-path/
Run Code Online (Sandbox Code Playgroud)
要将此更改应用于您打开的每个 shell,请将其添加到 shell在调用时将作为来源的文件。在不同的 shell 中,这可以是:
例如
# export PATH=$PATH:/root/learning/bin/
# source ~/.bashrc
# echo $PATH
Run Code Online (Sandbox Code Playgroud)
您可以在上面的输出中看到提供的路径。
在某些情况下,它使用PATH=/a/b:$PATH可能被认为是添加路径的“不正确”方式PATH:
PATH相同形式存在的路径。PATH采用不同形式的路径(即,由于使用符号链接或 导致的别名..)。PATH当它打算覆盖PATH.这个(Bash-only)函数在上述情况下做“正确的事情”(有一个例外,见下文),返回错误代码,并为人类打印好的消息。不需要时可以禁用错误代码和消息。
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 "$1" in
-f) tofront=true; shift;;
-n) errcode=0; shift;;
-q) qecho=':'; shift;;
*) break;;
esac; done
# Bad params always produce message and error code
[[ -z $1 ]] && { echo 1>&2 "$usage"; return 1; }
[[ -d $1 ]] || { $qecho 1>&2 "$1 is not a directory."; return $errcode; }
dir="$(command cd "$1"; 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"
}
Run Code Online (Sandbox Code Playgroud)
例外是此函数不会规范化PATH通过其他方式添加到的路径,因此如果路径的非规范别名在 中PATH,这将添加重复项。尝试规范化已经存在的路径PATH是一个冒险的命题,因为相对路径在传递给prepath时具有明显的含义,但是当已经在路径中时,您不知道添加时当前工作目录是什么。
小智 6
对我来说(在 Mac OS X 10.9.5 上),将路径名(例如/mypathname)添加到文件中/etc/paths效果很好。
编辑前,echo $PATH返回:
/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
Run Code Online (Sandbox Code Playgroud)
编辑/etc/paths并重新启动 shell 后,$PATH 变量将附加/pathname. 确实,echo $PATH返回:
/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/mypathname
Run Code Online (Sandbox Code Playgroud)
发生的事情是/mypathname已附加到$PATH变量。
这是我的解决方案:
PATH=$(echo -n $PATH | awk -v RS=: -v ORS=: '!x[$0]++' | sed "s/\(.*\).\{1\}/\1/")
Run Code Online (Sandbox Code Playgroud)
一个不错的简单单衬,不会留下拖尾 :
| 归档时间: |
|
| 查看次数: |
2783588 次 |
| 最近记录: |