Shell 的启动过程
Shell 的启动方式#
Shell 的启动方式会影响环境变量的加载过程,可分为以下几种。
- 交互式(Interactive)
- 登录:以登录方式启动的 Shell 实例,如 SSH 登录。
- 非登录:
- 在 Shell 中输入 Bash 新建 Shell 实例。
- 在 GNOME Terminal 中打开一个新的终端会话。
- 非交互式(Non-Interactive)
什么是交互式 Shell#
交互登录式#
在 Ubuntu 中,使用 SSH 登录时,文件的加载流程大致如下。
/etc/profile
:入口文件 - A,所有用户都会执行。/etc/bash.bashrc
:全局环境配置文件,A 会加载此文件。/etc/profile.d
:全局环境配置目录,A 会加载此目录的所有文件。~/.profile
:用户环境配置入口件文 - B。~/.bashrc
:用户环境配置文件,B 会加载此文件。
rc(Run Commands),源于 Unix 传统。
/etc/profile#
system-wide
:系统范围的配置文件。
/etc/bash.bashrc#
文件内容有点多,就看几行注释吧。
如果不是交互式(PS1 变量没有设置),则直接退出。
/etc/profile.d#
看一看目录的文件就好了。
~/.profile#
这个文件会去加载我们常常用到的 ~/.bashrc
文件。
看头部注释可以得知,如果 ~/.bash_profile
和 ~/.bash_login
存在的话,~/.profile
是不会被加载的,文件加载顺序如下。
~/.bashrc#
下面分析一下头部就差不多了。
看第一行注释,这个文件会被非登录 Shell 执行。
前面说到 ~/.profile
文件也会加载此文件,也就是说登录式 Shell 和非登录式 Shell 都会用到这个文件。
再来分析一下这些魔法代码(真的是天才设计🤪):
$-
是一个特殊变量,表示当前 Shell 运行时启用的选项,可以打印出来。
*i*
是一个匹配条件: $-
中是否包含 i
。i
选项表示当前 Shell 是交互式的。- 如果匹配成功,会退出 case。
- 如果匹配失败,会执行 return,退出当前脚本。
总结:如果不是在交互式中运行,直接退出,什么都不做。
交互非登录式#
这里讨论的是非登录的情况。例如:
- 在 Shell 中输入 Bash 新建一个 Shell 实例。
- 使用
()
执行命令分组时生成的 Subshell。 - 在 GNOME Terminal 中打开一个新的终端会话。
一句话总结:不加载 /etc/profile
,只加载 ~/.bashrc
。
非交互式#
这种方式没有命令行提示符,不会加载任可配置文件,即使手动加载 ~/.bashrc
,也不会生效。
因为上面的分析里提到,在非交互式中,会直接退出,什么都不做。
当然,你可以使用 BASH_ENV 变量来设置加载的文件,解释如下。
环境变量的持久化#
只需把环境变量写在对应的文件中,如:~/.bashrc
。