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: 同上。
当用户通过用户名、密码进入交互式shell的时候,加载配置文件的顺序如下:
/etc/profile -> /etc/profile.d/* -> ~/.bash_profile -> ~/.bash_login(前者不存在时) -> ~/.profile(前者不存在时) -> ~/.bashrc(被前序脚本触发)
验证如下:
在相关配置文件中插入一些echo语句,打印指定信息。
[root@ic-monitor01 ~]# grep ">>>" /etc/profile /etc/profile.d/* ~/.bash_profile ~/.bash_login ~/.profile ~/.bashrc /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"
采用ssh的方式登录一个交互式shell。
[root@ic-monitor01 ~]# ssh root@ic-monitor01 Password: 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-monitor01 Password: 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-monitor01 Password: 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确实按照顺位直接被执行了。
二、交互式非登陆shell的环境加载顺序
交互式非登录shell,指的是不需要用户名和密码即可打开的shell,比如在shell中直接执行“bash”来打开一个新的子shell。
当进入交互式非登录shell的时候,加载配置文件的顺序如下:
/etc/profile -> /etc/profile.d/*
验证如下:
[root@ic-monitor01 ~]# bash >>> ~/.bashrc >>> /etc/profile.d/test.sh
我们可以看到,它只重新加载了系统配置文件,用户配置文件并没有被重复加载,但是相关的变量设置已经直接被当前shell所继承。
三、一些环境配置的注意事项
* 系统配置,尤其是~/.bashrc这个最常用的用户配置文件,需要尽量保持干净,以防止一些系统变量设置冲突导致的shell环境无法进入。下面是一些常见的冲突项示例:
- 设置PS1变量,会导致ETX新开terminal无法进入shell环境。
- 直接设置anaconda的bin路径到PATH,会导致debus配置冲突,引起shell初始化失败。
* 分类别的全局系统/程序配置,在/etc/profile.d中以独立脚本的形式创建,比如module files的profile.sh配置文件,就可以copy/link到这个目录,作为全局的modules配置,这样更容易管理。