在 Linux 环境,服务器启动 / 使用各种 ssh 工具 (e.g. putty) 开启新的 session 登录时,系统会加载启动文件导入环境变量等。本文就是探讨启动文件的加载顺序。

启动文件

有两种类型的启动文件

全局文件:适用于所有登录服务器的用户。一般在​​/etc​​目录下。比如:

  • ​/etc/profiles​
  • ​/etc/bashrc​
  • ​/etc/bash.bashrc​

这些,一般都是需要 root 操作权限的。

用户文件:适用于某个用户。一般在用户自己的根目录下:​​~/​​, ​​/home/username/​​。比如:

  • ​.profiles​
  • ​.bash_profile​
  • ​.bashrc​
  • ​.bash_login​

这些,一般使用该用户账户登录即拥有所有操作权限。

以上这些启动文件,不一定每个都存在。但是如果存在多个的情况下,加载那个,先后顺序,有的时候尤为重要。

Shell 类型

Shell 有三种类型。下面一一介绍。因为不同类型的 Shell ,启动文件加载顺序不一样。

Interactive Login Shell

交互式登录 Shell ,比如​​ssh​​,​​putty​​,​​xterm​​,需要输一遍用户名密码登录的。(有的软件会存用户名密码,第二次登录就不需要输入了,但也属于这个类别。)

Interactive non-login Shell

交互式非登录 Shell,当你已经登录了这个 server ,再使用 ​​bash​​ 或者 ​​zsh​​ 开启一个新的 Shell 窗口,就不需要登录了。

Non-interactive Shell

非交互式 Shell,这个一般指 shell script 脚本,且非以​​#!/bin/bash​​开头。

顺序

参考网上总结的一张图,顺序如下:

按照 A->B->C 的顺序,如果同一类别有多个的话(如B1,B2,B3)就取第一个 available 的。

Linux Bash 文件加载顺序_bash

  • 总结1:先加载系统文件,后加载用户文件
  • 总结2:交互式登录的,一般先看​​~/.bash_profile​​,再看​​~/.profile​

Why it matters

简而言之:需要保证各个文件之间的兼容性。

最常见的一个 case , dev 使用 putty 登录上 server 后,即开启了一个​​Interactive Login Shell​​。然后跑了一个脚本(以​​#!/bin/bash​​开头),即开启了一个​​Interactive non-login Shell​​。这时,假设按顺序 load 了以下几个文件:

  • ​/etc/profile​
  • ​~/.profile​
  • ​~/.bashrc​

需要保证,最后 load 的 ​​~/.bashrc​​ 不会 "无意间地" 把前面定义好的环境变量覆写掉。

最佳实践思考

1.不要定义那么多不同的启动文件,尽可能只使用少量的1-2个文件,比如​​~/.profile​​,​​~/.bashrc​​。

2.灵活地在脚本中使用​​source​​。

3.对于只适用于 interactive mode 的,可以考虑加上​​[ -z "$PS1" ] && return​​判断条件。

参考