在/ etc / environment vs .profile中设置PATH变量


58

设置PATHenvvar 的首选位置在哪里?

~/.profile还是/etc/environment

PATH在两个地方都设置时会怎样?最终结果是在这两个地方设置的两个值的串联吗?


当然,最后一次分配给PATH是优先的。大多数脚本在脚本开始时都对其进行了显式设置。
AlexP

Answers:


69

摘要:

  • 如果您只想为当前用户而不是为计算机的所有用户/your/additional/pathPATH变量添加路径(例如),则通常将其放在这~/.profile两个示例之一的末尾,例如:

    PATH="/your/additional/path:$PATH"
    PATH="$PATH:/your/additional/path"
    

    请注意,路径优先级从左到右递减,因此第一个路径具有最高优先级。如果您在的左侧添加路径,则路径$PATH将具有最高优先级,并且该位置的可执行文件将覆盖所有其他路径。如果在右侧添加路径,则路径优先级最低,其他位置的可执行文件将是首选。

  • 然而,如果你需要设置环境变量为所有用户,我还是不建议动人/etc/environment,但与创建的文件名结尾的文件.sh/etc/profile.d/。该/etc/profile脚本和其中的所有脚本/etc/profile.d是每个用户个人的全局等效项,~/.profile并在初始化期间由所有shell作为常规shell脚本执行。


更多详情:

  • /etc/environment是系统范围的配置文件,表示所有用户都在使用它。但是它归所有者所有root,因此您需要成为管理员用户并用于对其sudo进行修改。

  • ~/.profile是您自己用户的个人shell初始化脚本之一。每个用户都有一个文件,可以编辑其文件而不会影响其他文件。

  • /etc/profile并且/etc/profile.d/*.sh是等效~/.profile于每个用户的全局初始化脚本。但是,全局脚本在用户特定脚本之前执行;并且main 在退出之前立即/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脚本。它只是一个以某种方式解析的配置文件,并且可能仅包含环境变量分配!

  • ~/.profile文件可以包含许多内容,默认情况下,它包含检查~/bin目录是否存在并将其添加到用户现有PATH变量中的其他内容,例如(在16.04之前的旧版Ubuntu上-无条件地将其添加):

    # set PATH so it includes user's private bin if it exists
    if [ -d "$HOME/bin" ] ; then
        PATH="$HOME/bin:$PATH"
    fi
    

    您会看到在PATH这里重用了旧值,并且新路径仅追加到开头,而不是覆盖所有内容。手动添加新路径时,还应始终将旧$PATH值保留在新字符串中的某个位置。

    该初始化脚本只能由其所属的用户的外壳读取,但是还有另一个条件:

    # ~/.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


相关问题:bash.bashrc和/ etc / environment文件之间的区别


2
如今~/.profile,不检查的存在~/bin,而只是检查以下内容:PATH="$HOME/bin:$HOME/.local/bin:$PATH"
Gunnar Hjalmarsson

1
@GunnarHjalmarsson定义“现在”,好吗?我正在运行16.04,这就是它的外观。
字节指挥官

2
/etc/skel/.profile在16.04中有我提到的行。您显然在先前版本中创建了您的用户。
Gunnar Hjalmarsson '16

1
@GunnarHjalmarsson感谢您提供信息-直到大约五分钟前,我还认为默认值~/.profile仍然具有此功能,但是您是对的- /etc/skel/.profile在升级后的16.04系统上没有此值(以及在16.04上安装时创建的用户帐户)另一台机器上没有.profile)。
伊利亚·卡根

2
“ ...在初始化期间,所有shell都将它们作为常规shell脚本执行。” 我认为这是误导。可能(对某些人)建议,仅从GUI桌面打开非登录终端外壳将执行/ etc / profile,而不会执行。askubuntu.com/questions/155865/...
鹰眼帕克

22

这个答案主要是关于在不同的配置文件中指定类似的环境变量时PATH所分配的顺序。我也介绍了通常应在何处进行设置,但下面的列表未按照应考虑使用它们的顺序列出文件。有关PATH在Ubuntu中设置和其他环境变量的一般信息,我还建议阅读EnvironmentVariables以及该问题的其他答案。

设置的首选位置PATH取决于您需要为其设置用户的时间以及设置时间和方式。决定的一部分将是要为所有用户还是基于每个用户设置环境变量。如果您不确定,建议您只为一个用户(例如您的帐户)而不是系统范围内的用户设置它。

AlexP所说PATH环境变量将具有它最近分配的值。实际上,在大多数情况下,您会设置PATH,将值包含PATH在新值中,以便保留先前的条目。

因此,实际上,当PATH从多个文件设置时,它通常包含所有文件中给定的条目。但这只是因为设置该PATH变量的所有文件(第一个文件除外)通常都引用该变量本身,从而导致其旧值包含在新变量中。

因此,您实际上是在要求PATH各种文件中的设置生效的顺序。

PATH下面列出了要设置的通用通用场所,顺序是用户登录时生效的顺序,而不是通常应考虑使用的顺序。下面列出的每个位置PATH 某些情况下都是设置的合理选择,但大多数情况下只有少数几个是不错的选择。

在下面的列表中,您会看到一些目录名称,例如~/.profile。如果您不熟悉tilde扩展,请~/参考当前用户的主目录。我主要将此语法用于紧凑性。Shell脚本支持该功能,但PAM配置文件支持。

1.对于所有用户: /etc/environment

Ubuntu上的PAM导致/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是常见的。)

您可以在任何的方式编辑这个文件,您可以编辑任何其他文件作为根用户(sudoedit /etc/enviromnmentsudo nano -w /etc/environmentgksudo 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.confpam_env.conf则使用in中的值-即使该值指定为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小节EnvironmentVariables(从中上面的例子中紧密地适应的),man pam_env以及man pam_env.conf进一步的细节。

尽管这曾经被吹捧为Ubuntu用户更改或添加环境变量的首选方式,并且仍然被认为是一种合理且可以接受的选择,但是在编辑时应格外小心.pam_environment。就像对系统范围的编辑一样/etc/security/pam_env.conf(请参见上文),用户.pam_environment文件中的格式错误的行将阻止登录成功。(我已经测试此-故意这段时间)有关如何信息的建议演变,看到贡纳尔Hjalmarsson评论 下面这个ubuntu-devel讨论

通常,这种错误比格式错误的行严重得多pam_env.conf,因为它仅影响一个用户。但是,如果桌面版Ubuntu系统只有一个允许登录的用户帐户,则编辑.pam_environment时发生的错误与错误编辑一样严重pam_env.conf-如果您尚未登录,则将无法进行在不以恢复模式(或从实时USB等)启动的情况下修复该问题。

(如果您确实拥有其他用户帐户,则可以以其他用户身份登录并解决问题。即使他们不是管理员并且无法sudoroot用户,他们仍然可以运行并提示您输入(不是他们的)密码来宾帐户无法执行此操作,因为该帐户被禁止使用其他用户的身份。)su your-accountsu

4.对于所有用户:/etc/profile和其中的文件/etc/profile.d/

当作为登录shell调用时bash,兼容Bourne的shell(包括Ubuntu中的默认用户shell)运行命令/etc/profile

Ubuntu的/etc/profile.d结尾是:

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是一个外壳脚本,其语法是一样的,上面讨论的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使用~/.profile,除非~/.bash_profile存在,否则bash会使用它代替(请参阅下文),在这种情况下,除非从`〜/ .bash_login发出,否则不会使用其他任何东西。

与一样.bash_profile,您通常不应.bash_login在主目录中有文件。

7.对于一个用户:.profile在用户的主目录中。

当Bourne风格的shell作为登录shell运行时,它将在/etc/profile其中运行命令(通常包括使文件中的命令/etc/profile.d/运行的命令-参见上文)。之后,它将.profile在用户的主目录中运行命令。该文件对于每个用户都是单独的。(实际上,Bash可以运行,.bash_profile或者.bash_login如果存在的话,而是运行-但是,对于Ubuntu系统上的用户,这些文件很少应该存在或确实存在。有关详细信息,请参见上文和Bash手册6.2 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

例如,.profileUbuntu上的默认每用户文件以以下结尾:

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

有关详细信息,请参见Gunnar HjalmarssonByte Commander答案评论

这将检查您是否具有bin主目录的子目录。如果是这样,则会将该子目录添加到的开头PATH

该列表忽略了一些可能性。

用户登录时,还有其他设置环境变量的方法,这些方法在很大程度上取决于登录类型。例如,您有时可能会为图形登录或仅基于SSH的远程登录设置环境变量。上面的列表不涵盖此类情况。

我遗漏了一些文件,人们有时会在其中定义环境变量,例如~/.bashrc/etc/bash.bashrc,因为通常不建议将它们设置PATH为环境变量,而且很少有您为此目的实际使用它们。如果使用这些文件向其中添加目录PATH,则有时它们会被添加很多次,并且在您检查时会非常混乱$PATH。(在极端情况下,这可能会使速度变慢,但通常只是保持所有内容的清洁和易于理解。)

由于bash是Ubuntu的默认用户登录外壳程序,并且大多数用户都使用它或其他兼容POSIX的外壳程序,因此我省略了有关如何在其他非伯恩风格的外壳程序中设置环境变量的信息tcsh


1
[第2条评论,第1条]感谢您提供的详尽说明!(我进行了少量编辑。)但是,对于建议的方式,我有疑问。几年前EnvironmentVariables提到/etc/environment/ ~/.pam_environment作为建议的文件。在咨询了开发人员之后,我将其更改为PAM和/etc/profile.d/*.sh/ 之间的中性~/.profile,并且我仍然倾向于这种方式。
Gunnar Hjalmarsson,2013年

1
[第2条评论,第2条]您提到了一些赞成PAM的论点。支持/etc/profile.d/*.sh/的重要参数~/.profile是语法更简单,并且在出现错误的情况下lightdm / gdm是可以原谅的(即使语法错误也无法阻止您登录,而只会导致警告消息)。
Gunnar Hjalmarsson

当你说的时候pam_env.so,你的意思是pam_env.conf
JohanBoulé

@JohanBoulé是的,我的意思是pam_env.conf。谢谢!我已对其进行修改以进行修复。
伊莱亚·卡根

3

/ etc / environment文件不是脚本文件,不能在那里使用export,它不支持$ HOME类型的变量扩展,仅支持simplevariable = value对。因此,要使用该文件,您只需要简单地将路径追加到现有定义中即可,这专门用于系统范围的环境变量设置。每行一个。具体来说,此文件存储系统范围的语言环境和路径设置。

〜/ .profile-该文件在执行bash shell时执行,通常是环境变量的推荐文件,但是它的缺点是只能由登录shell调用,因此,为了使它生效,您需要要注销并重新登录-或至少启动一个新的登录Shell。


1

设置环境变量的首选位置取决于几件事:

  1. 您是唯一使用计算机的人:
    • 在这种情况下,最好的位置是,/etc/environment因为不存在未经授权访问的危险。
  2. 如果系统被很多人使用
    • 如果所有人都应访问变量,则位置为/etc/environment,但
    • 如果单个用户应该选择对它们的访问权限,则每个~/.profile用户都应与系统每个用户有关的位置中设置他们的访问权限,因为它位于每个用户的主目录中。

系统将在读取/etc/environment之前先进行读取~/.profile。没有串联发生,就像Alex P所说的那样,最后的路径分配占了上风。

在确定如何的因素更详细的研究~/.profile,并/etc/environment与其他这样的位置打出去,在这里这里,因为这些因素会影响你如何使用这些位置。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.