它们是一个个shell脚本,这些文件包括:

  • /etc/profile
  • /etc/bashrc
  • ~/.bash_profile
  • ~/.bashrc
  • ~/.bash_login
  • ~/.profile
  • ~/.bash_logout

interactive login shell的执行顺序

下面是伪代码:

1
2
3
4
5
6
7
8
9
10
11
12
execute /etc/profile
IF ~/.bash_profile exists THEN
execute ~/.bash_profile
ELSE
IF ~/.bash_login exist THEN
execute ~/.bash_login
ELSE
IF ~/.profile exist THEN
execute ~/.profile
END IF
END IF
END IF

当登出交互式shell时,执行顺序是

1
2
3
IF ~/.bash_logout exists THEN
execute ~/.bash_logout
END IF

Note: /etc/bashrc是在~/.bashrc中被执行的

1
2
3
4
# cat ~/.bashrc
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi

interactive no-login shell的执行顺序

启动非登录交互式shell时,以下是执行顺序

1
2
3
IF ~/.bashrc exists THEN
execute ~/.bashrc
END IF

测试

我们用PS1来测试执行顺序。

/etc/profile被执行

添加下面的代码到/etc/profile, 然后重新登录。

1
2
3
4
5
6
[leon@192 ~]$ grep PS1 /etc/profile
PS1="/etc/profile> "
[leon@192 ~]$ su - leon
Password:
Last login: Sat Jan 4 04:14:53 CST 2020 on pts/0
/etc/profile> ls

~/.bash_profile~/.bashrc被执行

同样的,我们把这行代码添加到/.bash_profile, ~/bash_login, ~/.profile和/.bashrc中,然后再重新登录。

1
2
3
4
5
6
7
8
9
10
11
12
13
export PS1="~/.bash_profile> "
[leon@192 ~]$ grep PS1 ~/.bashrc
export PS1="~/.bashrc> "
[leon@192 ~]$ grep PS1 ~/.bash_login
export PS1="~/.bash_login> "
[leon@192 ~]$ grep PS1 ~/.profile
export PS1="~/.profile> "
[leon@192 ~]$ su leon
Password:
~/.bashrc> su - leon
Password:
Last login: Sat Jan 4 04:25:35 CST 2020 on pts/0
~/.bash_profile>

可以看到,如果shell是非登录交互式shell时,显示的是/.bashrc。而如果shell是登录交互式shell时,显示的是/.bash_profile。

~/.bash_login被执行

把~/.bash_profile重命名为其他名字,再重新登录。

1
2
3
4
5
~/.bash_profile> mv .bash_profile .bash_profile.bak
~/.bash_profile> su - leon
Password:
Last login: Sat Jan 4 04:25:45 CST 2020 on pts/0
~/.bash_login>

~/.profile被执行

把~/.bash_login重命名为其他名字,再重新登录。

1
2
3
4
5
~/.bash_login> mv .bash_login .bash_login.bak
~/.bash_login> su - leon
Password:
Last login: Sat Jan 4 04:35:47 CST 2020 on pts/0
~/.profile>

Reference