Linux 用户登录时的环境加载顺序

Linux系统 0 195 李艳青 收藏

       Linux 系统中有时会遇到一些登陆初始化故障,会阻止用户进入系统(比如 ETX 无法打开桌面)或者导致某些工具运行失败(LSF bsub 任务是无法完成初始化),所以了解 Linux 系统用户登录时的环境加载顺序,对 debug 和解决如上问题是很有帮助的。

 

一、交互式登陆 shell 的环境加载顺序

       交互式,指的是指通过终端输入命令并获得执行结果;登陆,指的是指需要用户名、密码登录后才能进入;shell,即我们常用的 bash/tcsh 等 shell 环境。这是最常见的一种使用模式。

       下面,我们以 linux 系统默认的 bash shell 为例,求证一下登陆 shell 时候的环境加载顺序,涉及到的系统 / 用户环境配置文件有如下几种:

/etc/profile: 用于系统环境设置 / 系统路径设置 / 通用系统配置 / 定义系统级别的行为,这些配置都是对全局用户生效的。

/etc/profile.d/*: 用于定义系统 / 应用的启动脚本,和 /etc/profile 相比,好处是可以和分散化和模块化配置,具有更好的可扩展性。

~/.bash_profile: 用于用户环境定制 / 定义用户别名 / 设置特定命令的行为 / 个性化提示符 / 配置用户特定的应用程序设置。

~/.bash_login: 同上,作为~/.bash_profile 的补充。

~/.profile: 同上。

~/.bashrc: 同上。

~/.bash_logout: 用于定义当前用户注销时执行的操作,包括清理 / 记录日志 / 发送通知 / 执行系统维护任务。

 

       当用户通过用户名、密码进入交互式 shell 的时候,加载配置文件的顺序如下:

/etc/profile  ->  /etc/profile.d/*  ->  ~/.bash_profile  ->  ~/.bash_login (前者不存在时)  ->  ~/.profile (前者不存在时)  ->  ~/.bashrc (被前序脚本触发)

 

       在退出当前登录时,系统会执行:

~/.bash_logout。

 

       验证如下:

       在相关配置文件中插入一些 echo 语句,打印指定信息。

[root@ic-monitor01 ~]# grep ">>>" /etc/profile /etc/profile.d/* ~/.bash_profile ~/.bash_login ~/.profile ~/.bashrc ~/.bash_logout/etc/profile:echo ">>> /etc/profile"/etc/profile.d/test.sh:echo ">>> /etc/profile.d/test.sh"/root/.bash_profile:echo ">>> ~/.bash_profile"/root/.bash_login:echo ">>> ~/.bash_login"/root/.profile:echo ">>> ~/.profile"/root/.bashrc:echo ">>> ~/.bashrc"/root/.bash_logout:echo ">>> ~/.bash_logout"

 

       采用 ssh 的方式登录一个交互式 shell。

[root@ic-monitor01 ~]# ssh root@ic-monitor01Password: 
Last login: Sun Apr  7 15:22:00 2024 from fe80::e42:a1ff:fe1c:4dae%ens192>>> /etc/profile>>> /etc/profile.d/test.sh>>> ~/.bash_profile>>> ~/.bashrc

       此种情况下,登陆顺序是 /etc/profile  ->  /etc/profile.d/*  ->  ~/.bash_profile  ->  ~/.bashrc (被前序脚本触发)

       因为~/.bash_profile 存在,所以~/.bash_login 和~/.profile 并没有被执行。

 

       去掉~/.bash_profile 再试。

[root@ic-monitor01 ~]# rm -rf ~/.bash_profile[root@ic-monitor01 ~]# ssh root@ic-monitor01Password: 
Last login: Sun Apr  7 17:46:12 2024 from fe80::e42:a1ff:fe1c:4dae%ens192>>> /etc/profile>>> /etc/profile.d/test.sh>>> ~/.bash_login-bash-4.2#

       ~/.bash_profile 被移除后,~/.bash_login 确实按照顺位直接被执行了。

       但是也注意到~/.bashrc 没有被执行就直接进入 shell 环境了,这是因为执行~/.bashrc 是~/.bash_profile 中定义的行为,~/.bash_profile 被移除后,~/.bashrc 也就没有地方会触发执行了。

 

       去掉~/.bash_login 再试。

[root@ic-monitor01 ~]# ssh root@ic-monitor01Password: 
Last login: Sun Apr  7 17:53:29 2024 from fe80::e42:a1ff:fe1c:4dae%ens192>>> /etc/profile>>> /etc/profile.d/test.sh>>> ~/.profile-bash-4.2#

       ~/.bash_profile 和~/.bash_login 被移除后,~/.profile 确实按照顺位直接被执行了。

 

       退出登录环境。

[root@ic-monitor01 ~]# ssh root@ic-monitor01Password: 
Last login: Mon Apr  8 07:32:52 2024 from fe80::e42:a1ff:fe1c:4dae%ens192>>> /etc/profile>>> /etc/profile.d/test.sh>>> ~/.bash_profile>>> ~/.bashrc
-bash-4.2# exitlogout>>> ~/.bash_logout
Connection to ic-monitor01 closed.

       此时~/.bash_logout 被执行,因此可以在~/.bash_logout 中增加一些后处理程序。

 

二、交互式非登陆 shell 的环境加载顺序

       交互式非登录 shell,指的是不需要用户名和密码即可打开的 shell,比如在 shell 中直接执行 “bash” 来打开一个新的子 shell。

       当进入交互式非登录 shell 的时候,加载配置文件的顺序如下:

~/.bashrc 

 

       验证如下:

[root@ic-monitor01 ~]# bash>>> ~/.bashrc
-bash-4.2#

       我们可以看到,它只重新加载了用户配置文件~/.bashrc,系统配置文件并没有被重复加载。

 

三、官方解释

       在 linux 系统中执行 man bash,可以看到官方文档中对登录 / 退出时执行文件的解释。

1.jpg

       咱们直译一下,内容如下。

   登录shell是参数0的第一个字符为-的shell,或者以-login选项开头的shell。
   交互式shell是在没有非选项参数和-c选项的情况下启动的,其标准输入和错误都连接到终端(由isatty(3)),或者以-i选项开始的一个。如果bash是交互式的,则设置PS1和$-includes i,允许shell脚本或启动文件测试此状态。
以下段落描述bash如何执行其启动文件。如果有任何文件存在但无法读取,bash会报告一个错误。
   Tildes在文件名中展开为下面在EXPANDION部分的Tilde Expansion下进行描述。
   当bash作为交互式登录shell调用,或者作为带有--login选项的非交互式shell调用时,它首先读取并执行文件/etc/profile中的命令,如果该文件存在。读取该文件后,它将按顺序查找~/.bash_profile、~/.bash _login和~/.profile,并读取并执行第一个命令中的命令
存在并且可读。当shell启动以禁止此行为时,可以使用--noprofile选项。
   当登录shell退出时,bash读取并执行文件~/.bash_logout和/etc/bash.bash_logout中的命令(如果这些文件存在的话)。
   当一个不是登录shell的交互式shell启动时,bash从~/.bashrc读取并执行命令(如果该文件存在的话)。这可以通过使用--norc来抑制选项--rcfile file选项将强制bash从文件而不是~/.bashrc中读取和执行命令。

 

四、一些环境配置的注意事项

* 如果个人定制环境设置,尽量只修改~/.bashrc 这个文件,以防止过多的配置来源无法定位。

* 系统相关配置,尤其是~/.bashrc 这个最常用的用户配置文件,需要尽量保持干净,以防止一些系统变量设置冲突导致的 shell 环境无法进入。下面是一些常见的冲突项示例:

  - 设置 PS1 变量,会导致 ETX 新开 terminal 无法进入 shell 环境。

  - 直接设置 anaconda 的 bin 路径到 PATH,会导致 debus 配置冲突,引起 shell 初始化失败。

* 分类别的全局系统 / 程序配置,在 /etc/profile.d 中以独立脚本的形式创建,比如 module files 的 profile.sh 配置文件,就可以 copy/link 到这个目录,作为全局的 modules 配置,这样更容易管理。


相关推荐:

网友留言:

您需要 登录账户 后才能发表评论

我要评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。
验证码