设置环境变量的首选位置是哪里PATH
?
~/.profile
或者/etc/environment
?
如果在两个地方都设置了,情况会怎样PATH
?最终结果是将这两个地方设置的值串联起来吗?
答案1
概括:
如果您只想为当前用户而不是计算机的所有用户向变量添加路径(例如
/your/additional/path
)PATH
,通常将其放在末尾,~/.profile
如以下两个示例之一所示:PATH="/your/additional/path:$PATH" PATH="$PATH:/your/additional/path"
请注意,路径优先级从左到右依次递减,因此第一个路径具有最高优先级。如果您在 的左侧添加路径
$PATH
,则该路径将具有最高优先级,并且该位置的可执行文件将覆盖所有其他位置的可执行文件。如果您在 的右侧添加路径,则该路径将具有最低优先级,并且其他位置的可执行文件将被优先使用。但是,如果您需要为所有用户设置该环境变量,我仍然不建议您动手,
/etc/environment
而是创建一个文件名以 结尾的文件。 该脚本和 中的所有脚本都是每个用户个人脚本的全局等效脚本,并.sh
在所有 shell 初始化期间作为常规 shell 脚本执行。/etc/profile.d/
/etc/profile
/etc/profile.d
~/.profile
更多详情:
/etc/environment
是系统范围的配置文件,这意味着它可供所有用户使用。它归系统所有root
,因此您需要成为管理员用户才能sudo
修改它。~/.profile
是您自己的用户的个人 shell 初始化脚本之一。每个用户都有一个,并且可以编辑他们的文件而不会影响其他人。/etc/profile
和/etc/profile.d/*.sh
是全局初始化脚本,对于每个用户来说都相当于~/.profile
。但是全局脚本会在用户特定脚本之前执行;主程序会在退出之前/etc/profile
执行所有脚本。*.sh
/etc/profile.d/
该
/etc/environment
文件通常只包含这一行:PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
它将
PATH
系统上所有用户的变量设置为此默认值,不应对其进行重大更改。至少您不应从中删除任何重要路径,如/bin
、/sbin
和。/usr/bin
/usr/sbin
此文件是每个用户的每个 shell 读取的第一个配置文件之一。请注意,它是不是 shell 脚本。它只是一个以某种方式被解析的配置文件,并且可能只包含环境变量分配!
该
~/.profile
文件可以包含许多内容,默认情况下,它包含检查~/bin
目录是否存在并将其添加到用户的现有PATH
变量中,如下所示(在 16.04 之前的旧 Ubuntu 版本中 - 无条件添加它 - 以及在 18.04 上,还添加“~/.local/bin”):# set PATH so it includes user's private bin if it exists if [ -d "$HOME/bin" ] ; then PATH="$HOME/bin:$PATH" fi
您会看到,旧的值
PATH
在这里被重用,而新路径仅附加到开头,而不是覆盖所有内容。当您手动想要添加新路径时,您还应该始终将旧$PATH
值保存在新字符串中的某个位置。这个初始化脚本只能被它所属的用户的shell读取,但是还有另外一个条件:
# ~/.profile: executed by the command interpreter for login shells. # This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login # exists.
因此,如果您使用默认的 Bash shell,则应确保您没有
~/.bash_profile
或~/.bash_login
希望更改~/.profile
对您的用户产生影响。
要全面了解环境变量,请参阅: https://help.ubuntu.com/community/EnvironmentVariables
答案2
这个答案主要关于
PATH
环境变量的分配顺序在不同的配置文件中指定时。我还介绍了通常应该在哪里设置它们,但下面的列表没有按您应该考虑使用它们的顺序列出文件。有关PATH
在 Ubuntu 中设置和其他环境变量的一般信息,我还建议阅读环境变量以及该问题的其他答案。
首选设置位置PATH
取决于哪些用户您需要将其设置为何时及如何您希望设置它。您的决定部分在于您是否希望为所有用户设置环境变量或基于每个用户设置环境变量。如果您不确定,那么我建议只为一个用户(例如,您的帐户)设置它,而不是为整个系统设置它。
作为AlexP 说,PATH
环境变量将具有原来的值最近分配。 在实践中,最多您设定的时间PATH
,包括老的新值中的值PATH
,以便保留先前的条目。
因此,实际上,当PATH
从多个文件设置时,它通常包含所有文件中给出的条目。但这种情况之所以发生,是因为除了第一个文件之外,设置它的所有文件通常都引用变量PATH
本身,从而导致其旧值包含在新值中。
PATH
因此,您实际上是在询问各个文件中的设置的生效顺序。
下面列出了常见的、通用的设置位置,PATH
按用户登录时生效的顺序排列,不是按照您通常应该考虑使用的顺序。下面列出的每个地方都是一个合理的选择PATH
在一些情况,但大多数时候只有少数是好的选择。
在下面的列表中,你会看到一些目录名称,例如~/.profile
。如果你不熟悉波浪号扩展,~/
指的是当前用户的主目录。我主要使用这种语法是为了简洁。它在 shell 脚本中受支持,但是不是在 PAM 配置文件中。
1. 对于所有用户:/etc/environment
聚丙烯酰胺在 Ubuntu 上,如果该文件存在,则将设置列出的环境变量/etc/environment
,默认情况下会设置。这就是为所有用户设置环境变量最常见的方式。
$ cat /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
如果必须设置环境变量全部用户帐户,而不仅仅是您的用户帐户,那么修改该文件可能是您的最佳选择。我建议先备份它。备份此文件的一种方法是运行:
sudo cp /etc/environment /etc/environment.orig
扩展.orig
名不是特别要求的——你可以放心地将备份文件命名为任何不会混淆或已经被使用的名称。(此外.orig
,、.old
和.backup
也.bak
很常见。)
您可以以 root 用户身份编辑任何其他文件的任何方式编辑此文件(sudoedit /etc/enviromnment
、、等)sudo nano -w /etc/environment
。gksudo gedit /etc/environment
/etc/environment
不支持自动包含变量的旧值。但这通常是不必要的,因为大多数情况下,您会通过编辑为所有用户设置环境变量/etc/environment
,无论如何,您都会希望该变量在用户登录时成为其初始值。然后用户可以根据需要更改它。通常,让用户能够这样做是件好事。
2. 对于所有用户:/etc/security/pam_env.conf
PAM 从 读取所有用户的环境变量/etc/security/pam_env.conf
,其指定语法与每个用户~/.pam_environment
文件中使用的语法相同(见下文)。
/etc/environment
当在和中设置相同的环境变量时/etc/security/pam_env.conf
,将使用中的值pam_env.conf
——即使该值指定为DEFAULT
而不是OVERRIDE
。
但是,当您用environment
中的一行取代 中的一行时pam_env.conf
,您可以包含被取代值的内容。.pam_environment
有关详细信息,请参阅下面的部分(因为它使用相同的语法)。
通常不需要编辑pam_env.conf
和如果你这样做,你应该非常小心,因为格式错误行通常会阻止所有普通用户帐户登录!例如,默认pam_env.conf
包含以下行:
#PATH DEFAULT=${HOME}/bin:/usr/local/bin:/bin\
#:/usr/bin:/usr/local/bin/X11:/usr/bin/X11
这是几个示例之一。它说明的一件事是如何用 将任务拆分为多行\
。假设您只取消注释第一行,但忘记取消注释第二行:
PATH DEFAULT=${HOME}/bin:/usr/local/bin:/bin\
#:/usr/bin:/usr/local/bin/X11:/usr/bin/X11
不要这样做!
我刚刚自己偶然测试了一下,结果发现所有用户都无法成功登录。为了修复这个问题,我必须在恢复模式下启动,然后再改回来。(幸运的是,我是在一台只用于测试的虚拟机上做的,所以没有给我带来任何麻烦。)
3. 对于一个用户:.pam_environment
在用户的主目录中
为单个用户设置环境变量的方法之一是让该用户.pam_environment
在其主目录中编辑(或创建)。此文件中设置的值将取代全局文件中设置的值/etc/environment
。
.pam_environment
不是最初创建用户帐户时复制到用户主文件夹中的文件骨架的一部分。但是,如果您在主目录中创建该文件,则可以使用它来设置环境变量,例如PATH
。与/etc/environment
(但类似/etc/security/pam_env.conf
)不同,每个用户.pam_environment
文件确实支持将环境变量的旧值扩展为新值。但是,它们不是 shell 脚本,您必须使用特殊语法来实现这一点,这与在文件(例如)中使用的语法略有不同.profile
。
例如,如果您bin2
的主目录中有一个目录想要添加到的末尾PATH
,您可以通过将以下行添加到来实现.pam_environment
:
PATH DEFAULT=${PATH}:/home/@{PAM_USER}/bin2
看本~/.pam_environment
节的环境变量(上面的例子与此非常相似),man pam_env
, 和man pam_env.conf
了解更多详情。
虽然这曾被吹捧为 Ubuntu 用户更改或添加环境变量的首选方式,并且仍然被认为是一种合理且可接受的选择,编辑时应小心.pam_environment
。与对系统范围的编辑/etc/security/pam_env.conf
(见上文)一样,用户.pam_environment
文件中格式错误的行将阻止登录成功。(我已经测试过这一点——这次是故意的。)有关如何建议有进化, 看古纳尔·哈尔马松的评论 以下和这次ubuntu-devel
讨论。
这样的错误不太严重,一般来说,比 中的格式错误的行更严重pam_env.conf
,因为它只影响一个用户。但是,对于只有一个允许登录的用户帐户的桌面 Ubuntu 系统,编辑时发生的此类错误.pam_environment
与编辑时发生的错误一样糟糕pam_env.conf
——如果您尚未登录,您将无法在不进入恢复模式(或从实时 USB 等)的情况下修复它。
(如果您有其他用户帐户,则可以以其他用户身份登录并解决问题。即使他们不是管理员,也无法sudo
root,他们仍然可以运行并提示输入您的(而不是他们的)密码。su your-account
客人但是,帐户不能这样做,因为它被禁止用来su
冒充其他用户的身份。)
4. 对于所有用户:/etc/profile
以及其中的文件/etc/profile.d/
与 Bourne 兼容的 shell(包括,Ubuntu 中的默认用户 shell)在作为登录 shell 调用时bash
运行中的命令。/etc/profile
Ubuntu 的/etc/profile
结尾是:
if [ -d /etc/profile.d ]; then
for i in /etc/profile.d/*.sh; do
if [ -r $i ]; then
. $i
fi
done
unset i
fi
/etc/profile.d/
这会导致目录中任何以 结尾的文件中的命令.sh
也被运行。
大多数显示管理器也会让 中的命令/etc/profile
(以及 中的文件/etc/profile.d
)在图形登录时运行。但是,并非所有人都能做到这一点,这是支持使用 PAM 提供的功能的一个重要理由(参见上文)——除非这个系统永远不会有任何图形登录,例如,如果它是一台没有安装 GUI 的服务器,那么可能就是这种情况。
在 中设置系统范围的环境变量是一种传统做法/etc/profile
,但这通常不再是最佳选择。如果您无法在 中设置环境变量/etc/environment
,而必须为所有用户设置它,那么在 中创建一个新文件可能/etc/profile.d/
比编辑/etc/profile
它本身更好。这样做的原因之一是,当 Ubuntu 升级时,可能会有一个新的默认/etc/profile
文件。根据您执行升级的方式,将保留旧文件(包含您的更改),放弃该特定的更新配置文件,或者将提示您处理这种情况。
/etc/profile
当在和中的一个或多个文件中设置相同的环境变量时/etc/profile.d
,最后执行哪一个?这取决于/etc/profile
设置它们的命令出现在文件profile.d
被调用之前还是之后(根据我上面引用的代码)。命令/etc/profile
按它们出现的顺序执行。
/etc/profile
是一个 shell 脚本,它的语法是不是与上面讨论的 PAM 配置文件相同。其语法与每个用户文件的语法相同~/.profile
(见下文)。
如果你需要编写代码决定是否要添加特定目录PATH
(以及是否为所有用户添加),您将无法使用/etc/environment
或/etc/security/pam_env.conf
来执行此操作。这也许是最好使用/etc/profile
或/etc/profile.d/
的主要情况。
5. 对于一个用户:.bash_profile
在用户的主目录中
如果用户有~/.bash_profile
,bash 会使用它来代替~/.profile
或(见下文)。通常,您的主目录中~/.bash_login
不应该有。.bash_profile
如果你这样做,它通常应该包含一个源命令~/.profile
(例如. "$HOME/.profile"
)。否则,每个用户.profile
文件的内容根本就不会运行。
6. 对于一个用户:.bash_login
在用户的主目录中
如果用户有~/.bash_login
,bash 会使用它来代替~/.profile
(见下文),除非~/.bash_profile
存在,在这种情况下,除非来自`~/.bash_login,否则不会使用其他任何一个。
与 一样.bash_profile
,您通常不应该.bash_login
在主目录中拥有文件。
7. 对于一个用户:.profile
在用户的主目录中。
当 Bourne 风格的 shell 作为登录 shell 运行时,它会运行 中的命令/etc/profile
(通常包括导致 中的文件中的命令/etc/profile.d/
运行的命令 - 请参阅上文)。之后,它会在.profile
用户的主目录中运行 中的命令。此文件对于每个用户都是独立的。(如果存在,Bash 实际上会运行.bash_profile
或.bash_login
—— 但是,对于 Ubuntu 系统上的用户来说,这些文件很少应该或确实存在。有关详细信息,请参阅上文和6.2 Bash 启动文件在Bash 手册。
~/.profile
因此是用户放置登录时运行的命令的主要位置。这是您设置 的传统位置PATH
,但由于 Ubuntu 具有 pam_env 模块并支持~/.pam_environment
,因此您应该考虑使用它。
与 一样/etc/profile
,并非所有显示管理器都会运行此文件进行图形登录,但大多数都会。~/.pam_environment
这是优先设置环境变量的原因(尽管有人可能更喜欢/etc/environment
这样/etc/profile
)。
PATH
设置时,您可以扩展环境变量,包括其本身(见上文)。但是,如果您需要以更复杂的方式设置,则可能必须使用您的。特别是,如果您想在每次用户PATH
登录时检查目录是否存在,并且仅在存在时才将其添加到,那么您将无法使用您的文件将该目录添加到您的。.pam_environment
PATH
.profile
PATH
.pam_environment
PATH
例如,.profile
Ubuntu 上的默认每个用户文件习惯结尾为:
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi
bin
这将检查您的主目录是否有子目录。如果有,它将把该子目录添加到PATH
.
该列表忽略了一些可能性。
用户登录时设置环境变量还有其他方式,这些方式在很大程度上取决于登录类型。例如,您偶尔可能会设置仅用于图形登录或仅用于基于 SSH 的远程登录的环境变量。上面的列表不包括此类情况。
我省略了一些人们有时会在其中定义环境变量的文件,例如~/.bashrc
和/etc/bash.bashrc
,因为通常不建议将它们设置为环境PATH
变量,而且您很少会将它们用于此目的。如果您使用这些文件将目录添加到PATH
,则有时会多次添加目录,当您检查时会非常混乱$PATH
。(在极端情况下,这可能会减慢速度,但通常这只是保持一切干净和易懂的问题。)
由于bash
是 Ubuntu 用户的默认登录 shell,并且大多数用户使用它或其他一些与 POSIX 兼容的 shell,所以我省略了有关如何在其他非 Bourne 风格的 shell(如)中设置环境变量的信息tcsh
。
答案3
/etc/环境文件不是脚本文件,您不能在那里使用导出,并且它不支持 $HOME 类型的变量扩展,只支持简单的变量=值对。因此,要使用该文件,您只需将路径附加到现有定义中,专门用于系统范围的环境变量设置。每行一个。具体来说,此文件存储系统范围的语言环境和路径设置。
〜/ .profile- 每当执行 bash shell 时都会执行此文件,通常是推荐的环境变量文件,但它的缺点是只能由登录 shell 调用,因此为了使其生效,您需要注销并重新登录 - 或者至少启动一个新的登录 shell。
答案4
bash 读取这些文件,但 zsh 不会:
全系统
/etc/profile
- 直接编辑它不是一个好主意。
/etc/profile.d/*.sh
- 来源:/etc/profile
会话范围内
~/.profile
https://help.ubuntu.com/community/EnvironmentVariables#A.2Fetc.2Fprofile.d.2F.2A.sh