如何正确添加路径到PATH?

如何正确添加路径到PATH?

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

这边走:

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或 中(如果您有的话)。 (如果您的登录 shell 是 zsh 而不是 bash,请将其放入~/.zprofile。)

配置文件是由登录 shell 读取的,因此只有在下次登录时才会生效。(有些系统将终端配置为读取登录 shell;在这种情况下,您可以启动一个新的终端窗口,但设置会生效)仅适用于通过终端启动的程序,如何设置PATH所有程序取决于系统。)

请注意,~/.bash_rc任何程序都不会读取它,它~/.bashrc是 bash 交互式实例的配置文件。您不应该在~/.bashrc.定义环境变量的正确位置是PATH~/.profile或者~/.bash_profile如果您不关心 bash 以外的 shell)。看它们之间有什么区别,我应该使用哪一个?

不要将其放入/etc/environmentor中~/.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

关于 bash 以外的 shell 的注释

在 bash、ksh 和 zsh 中,export是特殊的语法,并且两者都PATH=~/opt/bin:$PATHexport PATH=~/opt/bin:$PATH正确的事情。在其他 Bourne/POSIX 风格的 shell 中,例如 dash(在/bin/sh许多系统上),export被解析为普通命令,这意味着两个区别:

因此,在像 dash 这样的 shell 中,export PATH=~/opt/bin:$PATH设置PATH为文字字符串,后跟直到第一个空格 ~/opt/bin/:的值。 (一个裸作业)PATHPATH=~/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)。

1在 Bourne shell 中情况并非如此(就像在实际的 Bourne shell 中,而不是现代 POSIX 风格的 shell),但现在您不太可能遇到这种旧的 shell。

答案2

Appending/Prepending 的防弹方式

附加/前置的常用方法

PATH="$PATH:~/opt/bin"   # appending
PATH="~/opt/bin:$PATH"   # prepending

可能会带来剧烈的头痛。

防弹方式将路径(例如,~/opt/bin)添加到 PATH 环境变量是

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

为什么?

这可以避免最初为空时出现虚假的前导/尾随冒号$PATH,这可能会产生不良的副作用,并且可能会成为一场噩梦,难以找到(这个答案简单地处理这个案例awk)。

解释(从外壳参数扩展):

${parameter:+word}

如果为 null 或未设置,则不替换任何内容,否则替换parameter的扩展。word

因此,${PATH:+${PATH}:}被扩展为:

  1. 什么都没有,如果PATH为空或未设置,
  2. ${PATH}:,如果PATH已设置。

笔记:这是用于 bash 的。


我想知道为什么系统脚本通常不使用它。 编辑:我刚刚发现像这样的脚本devtoolset-6/enable实际上使用了这个,

$ cat /opt/rh/devtoolset-6/enable
# General environment variables
export PATH=/opt/rh/devtoolset-6/root/usr/bin${PATH:+:${PATH}}
...

答案3

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

特别是,从安全的角度来看,在前面添加路径是危险的,因为如果有人可以获得对您的 的写访问权限~/opt/bin,他们可以在其中放置一个不同的路径ls,然后您可能会使用它的/bin/ls不经意间。现在想象一下您的浏览器或选择是否相同ssh...(将 . 放入您的路径中也是如此。)

答案4

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

PATH=/data/myscripts:$PATH

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

PATH=$PATH:/data/myscripts

但前面的内容还不够,因为当您在脚本内设置环境变量时,该更改仅在脚本内有效。解决这个限制只有两种方法:

  • 如果在脚本中导出环境变量,则该环境变量在脚本调用的任何程序中都有效。请注意,它在调用脚本的程序中无效。
  • 如果调用脚本的程序通过包含而不是调用来执行此操作,则脚本中的任何环境更改都会在调用程序中生效。这种包含可以通过 dot 命令或 source 命令来完成。

例子:

$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,并且由于存在导出语句,bash 调用的任何程序都具有更改后的$PATH变量。由于从 bash 提示符运行的任何程序都由 bash 调用,因此新路径对于从 bash 提示符运行的任何程序都有效。

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

更多信息这里

相关内容