在说配置文件的加载顺序之前,我们需要了解一下
Shell
的启动方式。
Shell
启动方式
- 交互式登录
- 交互式非登录
- 非交互式登录
- 非交互式非登录
交互式
:一个个地输入命令并及时查看它们的输出结果,整个过程都在跟 Shell 不停地互动。
非交互式
:运行一个Shell 脚本
文件,让所有命令批量化、一次性地执行。
登录式
:需要输入用户名和密码才能使用。
非登录式
:直接可以使用。
如何判断是否为交互式
Shell
? 有两种方式- 查看特殊变量
-
,如果值包含i
,则是交互式,否则是非交互式
$ echo $-
- 查看变量
PS1
是否为空,如果不为空,则是交互式,否则为非交互式
$ echo $PS1
- 查看特殊变量
如何判断是否为登录式
Shell
?
执行命令shopt login_shell
,如果login_shell
的值为on
表示登录式,为off
表示非登录式。
同时判断交互式和登录式
$ echo $PS1; shopt login_shell
配置文件加载顺序
对于登录式和非登录式,配置文件的加载顺序是不一样的。
与Bash Shell
有关的配置文件主要有/etc/profile、~/.bash_profile、~/.bash_login、~/.profile、~/.bashrc、/etc/bashrc、/etc/profile.d/*.sh
,不同的启动方式会加载不同的配置文件。
1. 登录式 Shell
Bash
官方文档说:如果是登录式的 Shell
,那么首先会读取和执行 /etc/profiles
,这是所有用户的全局配置文件
,接着会到用户主目录
中寻找 ~/.bash_profile、~/.bash_login
或者~/.profile
,它们都是用户个人的配置文件。
不同的 Linux
发行版附带的个人配置文件也不同,有的可能只有其中一个,有的可能三者都有。如果三个文件同时存在的话,那么到底加载哪一个呢?它们的优先级顺序是 ~/.bash_profile > ~/.bash_login > ~/.profile
。
如果 ~/.bash_profile 存在,那么一切以该文件为准,并且到此结束,不再加载其它的配置文件。
如果 ~/.bash_profile 不存在,那么尝试加载 /.bash_login。/.bash_login 存在的话就到此结束,不存在的话就加载 ~/.profile
笔者 CentOS7
的 /etc/profile
文件有如下一段代码:
for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do
if [ -r "$i" ]; then
if [ "${-#*i}" != "$-" ]; then
. "$i"
else
. "$i" >/dev/null
fi
fi
done
这段脚本的大致意思就是:遍历 /etc/profile.d
目录下所有以 .sh
结尾的文件和 sh.local
文件。判断它们是否可读([ -r "$i"]
),如果可读,判断当前 Shell
启动方式是不是交互式($-
中包含 i
)的,如果是交互式的,在当前 Shell
进程中执行该脚本(. "$i"
,source "$i"
的简写, Shell
的模块化方式),否则,也在当前 Shell
进程中执行该脚本,只不过将输出重定向到了 /dev/null
中。
${-#*i}
这个表达式的意思是:从左向右,在 -
变量中找到第一个 i
,并截取 i
之后的子串。
类似的 ~/.bash_profile
中有如下一段代码
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
意思就是执行 ~/.bashrc
脚本
总结:在登录式方式下,配置加载顺序是:
/etc/profile > /etc/profile.d/*.sh /etc/profile.d/sh.local > ~/.bash_profile > ~/.bashrc > ~/.bash_login > ~/.profile
一般如果是对所有用户添加配置,可以添加到 /etc/profile
文件中,如果只想给当前用户添加配置,可以添加到 ~/.bashrc
中。
2. 非登录式 Shell
如果以非登录的方式启动 Shell
,那么就不会读取以上所说的配置文件,而是直接读取 ~/.bashrc
。所以一般建议将配置直接添加在 ~/.bashrc
中,这样不管是登录式 Shell
还是 非登录式 Shell
都可以读到。