%%
# 纲要
> 主干纲要、Hint/线索/路标
# Q&A
#### 已明确
#### 待明确
> 当下仍存有的疑惑
**❓<font color="#c0504d"> 有什么问题?</font>**
# Buffer
## 闪念
> sudden idea
## 候选资料
> Read it later
%%
# 初始化配置文件
**初始化文件**包括三类:
- **PAM 文件**:存在着**每次进行 ==PAM 认证==时将自动执行的命令**
- **登录文件** (login file):存放着 **==登录 shell 启动时==将自动执行的命令**
- **环境文件** | **bash shell 配置文件**(environment file):存放着 **==新 shell 启动时==将自动执行的命令**
三类文件的具体路径:
| | PAM 文件 | 登录文件 | bash shell 配置文件 |
| --- | ----------------------------------------------------- | ----------------------------------------------------------------------- | --------------------------------------- |
| 系统级 | `/etc/environment` 以及 <br>`/etc/environment.d/*.conf` | `/etc/profile` 以及 <br> `/etc/profile.d/*.sh` | `/etc/bash.bashrc` 或 <br> `/etc/bashrc` |
| | | | |
| 用户级 | `~/.pam_environment` | `~/.bash_profile` <br>`~/.bash_login` <br>`~/.profile` <br>(通常只有三者之一) | `~/.bashrc` |
其中,**"系统级" 表示对所有用户有效,而 "用户级" 则是各用户特异的配置文件**。
> [!NOTE]
> **以不同方式(==登录或交互式==)启动 shell 时,会执行不同的初始化文件**。
> 同时用户级文件的执行顺序**晚于**系统级文件,因此 **"用户级" 配置将会覆盖 "系统级" 配置**。
> [!NOTE] **图形化界面组成部分(比如 GUI 客户端)的环境变量**可能需要在**另外一些配置文件中**设置,与设置 bash shell 环境变量的文件不同。
> [!NOTE] 系统级配置文件说明
>
>
>
> ![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-1A8C2AD0134121FEE75250CBB711D850.png|643]]
>
<br>
## 登录文件
即 "**登录 shell 配置文件**",每次 "**启动一个==登录 shell==**" 时将会自动执行的脚本文件。
- **系统级**登录配置文件:
- **`/etc/profile`** 文件
- **`/etc/profile.d/` 目录**下的 `.sh` 文件:
- **用户级**登录配置文件:
- `~/.bash_profile` 或 `~/.bash_login` 或 `~/.profile` 文件(通常只有三者之一)
<br>
## bash shell 配置文件
每次**启动一个 "==新的 bash shell==" 时**将会自动执行的脚本文件。
- **系统级** bash shell 配置文件:**`/etc/bash.bashrc`** 或 **`/etc/bashrc`** 文件
- **用户级** bash shell 配置文件:**`~/.bashrc` 文件**
> [!summary] **`profile` 文件与 `bashrc` 文件区别**
>
> ![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-A2BC665156A0AD3C3398128C6873BFFD.png|672]]
>
> - `profile` 文件是**系统或某个用户** **==设置环境变量==** 的配置文件,单个用户可以有多个 shelll (例如 bash, sh, zsh) 等,但环境变量通常应当是通用的,因此应该统一放在 `profile` 中。
>
> - `bashrc` 是 "**==bash shell 的配置文件==**",用于**初始化 bash 设置**,例如 bash 的代码补全、bash 的别名、bash 中的颜色等等,**也可设置特定于 bash 的环境变量**。
>
<br><br>
## PAM 文件
> [!NOTE] 可拆卸式认证模块 PAM
>
> Lunix 系统中,**可拆卸式认证模块**(Pluggable Authentication Module,**PAM**)负责处理**用户认证、账户、会话和密码相关**的各种任务。
>
> **PAM 认证过程**主要发生在以下两个场景:
>
> - **用户登录时**:无论是通过图形界面登录,还是通过命令行方式,当用户登录到系统,用户会话开始时,PAM 相关模块就会被触发,用来**认证用户、设置用户会话**等;
> - **需要身份验证的服务请求时**:例如,当用户视图使用 `sudo`、更改密码,或是通过远程服务进行身份验证时,PAM 模块也会被调用。
>
> **PAM 的认证过程**会==**先于登录 shell 执行**==,在 PAM 认证过程中,PAM 模块(特别是 `pam_env` 模块)将会读取**PAM 文件**,以**设置环境变量**。
>
> `pam_env` 模块是 PAM 的一部分,用于管理用户会话的环境变量。
**PAM 文件** 不是 shell 脚本文件,而是 **==文本文件==,以 `KEY=VALUE` 的形式,每行定义一个环境变量**。
PAM 文件包括:
- `/etc/environment` **系统级 PAM 文件**。
- `/etc/environment.d/` **目录**下的所有配置文件:`/etc/environment.d/*.conf` 文件
- `~/.pam_environment` **用户级 PAM 文件**(不一定存在)。
上述文件在**每个用户会话开始时**被会被 PAM 模块读取,以获取系统级环境变量,而不仅仅是在系统首次启动时,即**每次用户登录时**,无论是**重启后的登录**还是**系统运行中的登录**。由此,确保所有用户会话都能获取到定义在该文件中的环境变量。
##### `/etc/environment` 文件
系统级 PAM 配置文件,文件只有一行内容,定义 `PATH` 环境变量:

> [!note] 关于 `/etc/environment`
>
> 该文件用于为那些 "由系统启动(systemd)的进程" 设置环境。shell 不会读取该文件。
> set up environment for all process run by the system。systemd)
>
> ![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-324F21EAF084A533700F33923EB4FF3C.png|641]]
>
>
##### `/etc/environment.d/*.conf` 文件
**`/etc/environment.d/` 目录** 用于供管理员和各种软件包**在独立的文件中添加环境变量配置**,而不是直接编辑 `/etc/environment` 文件。
通常,每个 tool 会对应一个独立的 `*.conf` 文件。

##### `~/.pam_environment` 文件
用户级 PAM 配置文件。
<br><br>
# 初始化配置文件的加载顺序
![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-79F614CF528373C19D8721B006AA4160.png|525]]
以 Ubuntu 为例,对**环境变量相关文件**的加载包括两部分:
- **PAM 模块**对 **PAM 文件**的加载

- **shell** 对**相关配置文件**的加载
- 对于 **==非交互式登录 shell==**,加载顺序如下(例如,通过 `bash -l` 来执行一个 shell 脚本时)
- `/etc/profile`
- `~/.profile`
- 对于 **==交互式登录 shell==**,加载顺序如下(例如,通过虚拟控制台、终端模拟器启动的**登录 Shell**)
- `/etc/profile`
- -> `/etc/bash.bashrc`
- -> `/etc/profile.d/*.sh`
- `~/.profile`
- -> `~/.bashrc`
- 对于 **==交互式非登录 shell==**,加载顺序如下(例如,图形界面下**打开一个新的终端模拟器时**)
- `/etc/bash.bashrc`
- `~/.bashrc`
### 图形界面环境下的配置文件加载
> [!NOTE] 图形环境下的配置文件加载
>
> 相关术语:
>
> - **图形界面环境**(GNOME、KDE、XFCE 等)
> - **显示管理器**(如 GDM (GNOME Display Manager)、LightDM、SDDM 等)
> - 负责提供**图形登录界面**,**管理用户身份验证和启动图形会话的程序**
> - **图形会话进程**(例如 `gnome-session`、`kde-session` 、`xfce-session`)
> - 负责设置图形环境相关的环境变量和启动应用程序,启动窗口管理器等
> - **图形环境下的终端模拟器**(`GNOME Terminal`、`Konsole`、`XFCE Terminal`)
>
>
> 当用户通过**图形登录界面**(GDM、LightDM、SDDM 等)登录时,**显示/会话管理器**将会启动一个**图形会话进程**(图形用户界面会话),此后用户进入到**图形桌面环境**(GNOME、KDE、XFCE 等)。
>
> **在这一过程中并==不会涉及启动 shell==**,但 **==图形会话管理器"通常"会通过一些机制(例如图形环境的启动脚本)来读取 `/etc/profile` 以及 `~/.profile` 登录配置文件==,从而确保正确设置用户环境,以便在整个图形会话中都可用**。
> (取决于发行版和桌面环境,会存在一些不同,例如,一些桌面环境可能会为了应用全局环境设置而读取 `/etc/environment` 或者通过 PAM 模块 `pam_env.so` 来应用 `/etc/security/pam_env.conf` 文件的设置)
>
> 当在图形界面下**打开一个终端模拟器**时,默认会启动一个 **交互式非登录 shell**,此时**该交互式 shell 将会读取对应的 shell 配置文件(例如 `/etc/bash.bashrc` 以及 `~/.bashrc`)**。
>
> 当在图形界面下**打开一个虚拟控制台**时(例如通过 `Ctrl+Alt+F1~F6` ),则该虚拟控制台将启动一个**交互式登录 shell**,此时将会读取对应的**登录配置文件**以及 **bash 配置文件**。
> [!caution]
>
> `~/.bashrc` 中的环境变量,**对于从图形界面下直接启动的程序不生效**,因为没有启动 shell。
>
> ![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-D431B310A23A8660D8761F01AEE1E02E.png|822]]
>
>
<br><br>
# 环境变量配置建议
- 配置**系统级环境变量**(Linux 系统中所有用户所有进程可见):
- **最好**在 `/etc/profile.d/` 目录中创建一个以 `.sh` 结尾的文件,放置**所有新的或修改过的全局环境变量**。
- **或者**放在 `/etc/bashrc.bashrc` 中
- **不建议**放在 `/etc/profile` 中,因为一旦升级系统版本该文件会被覆盖,所有自行修改的内容都会丢失。
- **禁止**修改 `/etc/environment` 文件。
- 配置**用户个人的环境变量**:
- **推荐**设置在 `~/.bashrc` 文件中。参见下文笔记"shell 启动文件加载"。
> [!info] 对于系统级环境变量,只应当在 `/etc/profile.d` 下创建独立文件来**定义新的或修改已有的环境变量**
>
> 不应当修改 `/etc/profile` 文件,原因如下:
>
> ![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-B69DC69515BAABE997C580E19C72E985.png|959]]
>
> 不应当修改 `/etc/environment` 文件,原因如下:
>
> ![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-5F6631E698A15E3955690FF257B820EF.png|692]]
>
> ![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-14D66E1AFCE91AE553D3864ADDF11362.png|684]]
>
### 添加环境变量示例
示例一:放到 `~/.bashrc` 中
![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-DD55169F31071EBC7D6AA31B0B08B2C9.png|649]]
示例二:设置 JDK 环境变量,放到 `/etc/profile.d/java.sh` 中

---
<br><br><br>
# shell 启动配置文件(Startup File)
> 参见 GNU Bash 官方文档:[Bash Startup Files (Bash Reference Manual)](https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html)
![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-15CFD279DB18594897BC5D276816415C.png|971]]
bash shell 进程**启动时**会根据 **shell 的启动类型**来加载执行对应的**特定配置文件**(参见[[#初始化配置文件]])
**shell 启动类型**包括**两个独立维度**的划分:"**登录/非登录**" 与 "**交互式/非交互式**",
- 对于 **==登录 shell==**,其在启动时会直接加载 "**==登录文件==**"。
- 对于 ==**交互式 shell**==,其在启动时会直接加载 "**==bash shell 配置文件==**"
上述两个属性**彼此独立**,互不影响,因此:
- 对于 "**==交互式登录 shell==**",其在启动时会被保证**既加载 "登录文件",也加载 "bash shell 配置文件"**。
- 对于 "**==非交互式非登录 shell==**",则通常**不会加载任何配置文件**(会继承父 shell 的环境变量),<br>只会对 **环境变量 `BASH_ENV`** 进行检查,如果存在则**其指向的文件将会被读取并执行**。
> [!NOTE] 使配置文件生效
>
> - 修改 **==登录配置文件==** `/etc/profile` 或 `~/.bash_profile` 或 `~/.bash_login` 或 `~/.profile` 后,需要:
> - **重新登录**(触发 **登录 shell** 对这些文件的加载与执行)才能**对当前用户有效**。
> - 也可使用 `$ source /etc/profile` 命令加载配置文件,使其**在当前 shell 中**生效。
>
> >
>
> - 修改 **==bash 配置文件==** `/etc/bash.bashrc` 或 `~/.bashrc` 后,只需
> - **重新打开一个 shell 就会在新打开的 shell 生效**。
> - 也可使用 `$ source /etc/bash.bashrc` 使其在当前 shell 中生效。
>
<br><br>
# shell 启动类型划分
> 在《Unix & Linux 大学教程》第 12 章、14 章有非常明确的介绍。
#### 交互式登录 shell
- 当用户通过 SSH 登录到远程服务器时,或者通过控制台( tty) 直接登录系统时,启动的是一个**交互式登录 shell**。
- 使用 `su -` 或 `su -l ` 命令切换用户时,将启动**交互式登录 shell**。
- 使用 `bash -l` 或 `bash --login` 命令打开一个新的 shell 时
#### 非交互式登录 shell
- **通过 `bash` 解释器并带有 `--login` 或 `-l` 参数** 来**运行 shell 脚本**时,启动一个**非交互式登录 shell**。
- 例如 `bash --login script.sh`
- 例如 `ssh user@host "bash --login c 'some-command'"` 时。
#### 交互式非登录 shell
- 当用户在**已登录的终端模拟器**上打开**新的终端窗口或标签页**时,启动一个**交互式非登录 shell**。
- 在一个 shell 进程中**创建一个子 shell 进程**时,子进程作为**交互式非登录 shell** 启动。
- 使用 `su` 命令切换用户时,默认为**交互式非登录 shell
- 使用 `bash` 命令打开一个新的 shell 时,默认为**交互式非登录 shell
#### 非交互式非登录 shell
- **通过 `bash` 解释器**,或者**直接通过脚本名**运行 shell 脚本时,该脚本**在非交互式非登录 shell 中执行**。
- 例如, `$ ./myscript.sh`
- 例如, `$ bash myscript.sh`
> [!summary]
>
> 场景总结
>
> ![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-B1D0FCEC97EE0FF8E8560A58891B0CD0.png|800]]
>
>
<br>
#### 说明示例
- 通过 SSH 远程登录到服务器,shell 以 **交互式登录 shell** 的方式运行:
![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-4BA234D7D063E68CCC22F8EC5653F1B5.png]]
- 通过虚拟控制台 tty 直接登录时: **交互式登录 shell**

- 通过终端窗口(GNOME-terminal)打开的 shell:**交互式非登录 shell**
> 许多现代 Linux 发行版使用图形登录屏幕。当用户通过图形界面登录后,然后打开终端窗口(如 gnome-terminal, konsole 等),此时启动的 shell 实例是一个**交互式非登录 shell**。这是因为**图形会话管理器已经作为登录 shell 启动**,并处理了相关的登录脚本。此后在此会话中启动的所有终端都被认为是非登录 shell。
> 
- 使用 `su -` 或者 `su -l ` 命令切换用户时,启动 **交互式登录 shell**。

- 使用 `bash -l` 命令启动一个新的 bash 时,启动 **交互式登录 shelll**
![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-93F6A7ADB89D230038033B86057F6BD9.png|650]]
<br><br><br>
# shell 启动类型判断
### 判断是否为登录 shell
###### (1)通过 `shopt | grep login_shell` 命令判断
![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-90B1D0C79C1B2C337369E22891BC1920.png]]
Bash 在作为登录 shell 启动时,会设置 `shopt` 的 `login_shell` 选项,因此可通过上述命令检查该选项。
###### (2)通过 `echo $0` 判断(存在局限性,不一定准确,并不总是反映 shell 的登录状态)
当 Bash 作为登录 Shell 启动时,其第 0 个参数(即 `$0`,通常是程序名)**将以 `-` 字符开头**。
因此,可通过命令 `echo $0` 检查环境变量 `0` 的值进行判断:
- 如果输出以 `-` 开头(如 `-bash`),则表明当前 Shell 是登录 Shell。
- 如果输出不以 `-` 开头(如 `bash` 或其他路径/名称),则表明当前 Shell 不是登录 Shell。
> [!caution]
>
> `$0` 并不总是反映 shell 的登录状态
>
> 在某些情况下,例如 Bash 作为一个子 bash 启动时(例如 `bash --login`),虽然该实例作为登录 shell 启动(这可以通过 `shopt | grep login_shell` 显示为 `on` 确认),但是 `$0` 的值显示为 `bash`。
>
> ![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-9896B0F5957F121526C4192F4B35B6C1.png]]
>
> 这是因为 **`$0` 通常显示的是启动 Shell 的命令名或脚本名,==并不总是反映 Shell 的登录状态==**。
<br>
### 判断是否为交互式 shell
###### (1)通过 `shopt | grep interactive_comments` 命令判断
![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-230501DC7F4D97DCDEB8D7B4B0252C31.png]]
###### (2)检查变量 `$-` 进行判断:`echo $-`
`
在 Bash 中,特殊变量 `$-` 包含了当前 Shell 选项,如果这个字符串包含字符 `i`,那么 Shell 就是交互式的
![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-C20F2B964316113DD5A29BEB7832A3C8.png|248]]
###### (3)检查变量 `PS1` 进行判断:`echo $PS1`
`PS1` 环境变量通常在交互式 Shell 中设置,用于定义命令提示符。如果 `PS1` 被设置了,那么通常意味着 Shell 是交互式的
![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-1504F91017F689E73E133B21AC1CD07F.png|500]]
<br><br><br>
# 登录 shell
### 登录 shell 的特性
登录 shell 是:**参数 `$0` 的首字符为 `-`**(如 `-bash`),或者**带有 `--login` 或 `-l ` 选项启动的 shell**。
登录 shell 在退出时,**会执行脚本 `~/.bash_logout`**(如果存在)。
### 登录 shell 加载的配置文件
登录 shell 在**启动时**会**直接加载** "**==登录文件==**" :
- ==**系统级==登录配置文件**:**==任何用户==** 每次启动 **登录 shell** 时都会执行该文件
- **`/etc/profile` 文件**,其中:
- 包含对 **`/etc/bash.bashrc` 文件**的加载(仅对于==**交互式 shell**==)
- 包含对 **`/etc/profile.d/` 目录下所有 `.sh` 脚本文件**的加载(`/etc/profile.d/*.sh)
- **==用户级==登录配置文件**:**==用户个人==** 的**登录配置文件**
- **`~/.bash_profile`** 或 **`~/.bash_login`** 或 **`~/.profile`** 文件(通常不会全部包含)
- 按上述顺序**依次查找**,只**读取和执行找到的第一个文件**,而忽略其余文件。
- 上述文件中,包含对 **`~/.bashrc` 文件** 的加载(仅对于==**交互式 shell**==)
**登录 shell 不会直接加载 bash 配置文件**,
但在 "**登录配置文件**" 中通常会为 "**==交互式 shell==**" 加载**系统级/用户级 ==bash 配置文件==**。
(具体调用细节在不同发行版中可能存在差异)
这一点**保证**了对于"**==交互式==登录 shell**" 会加载应用 "**登录配置文件**" 以及 "**bash shell 配置文件**"。
> [!info] Ubuntu 下 "==**登录文件**==" 中包含对 "**==bash 配置文件==**" 的调用
>
> 1. **`/etc/profile` 文件中为 "==交互式 shell==" 加载了系统级 bash 配置文件 `/etc/bash.bashrc`**
> 2. **`~/.profile` 文件中加载了用户级 bash 配置文件 `~/.bashrc`**
> [!info] Ubuntu 下的 `/etc/profile` 文件
>
> Set up environment used and propagated from the login shell.
> This file get executed whenever **a bash login shell is entered**(e.g. when logging in from the console or over ssh.
>
> ![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-243A250D6E5137BA3DC48C1F8F580EE3.png|450]]
>
>
> 1. 对于**交互式 shell**,该文件会**加载 `/etc/bash.bashrc` 文件**:
> - 检查 **==当前 shell 是否为交互式 shell==**:`if [ "${PS1-}" ]; then`
> - `PS1` 是 **shell 主提示符**对应的环境变量,通常**只在交互式 shell 中会被设置**,由此判断当前 shell 是否为**交互式 shell**
> - 检查 **==当前 shell 是否为 bash==**,并且**不是以 `/bin/sh` 这一兼容模式运行**:<br> `if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then`
>
>
>
> 2. 加载了 **`/etc/profile.d/` 目录** 下的所有 `.sh` 脚本文件。
> [!info] Ubuntu 下的 `~/.profile` 文件
>
> ![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-62EB4A402FC08AEE0A780F0D97ADE285.png|573]]
>
> - 该文件中加载了 `~/.bashrc` 文件
>
<br><br>
# 交互式 shell
### 交互式 shell 特性
交互式 shell **允许用户与其交互**,用户可以在 CLI 的**命令行提示符**( `
或 `#`)后输入命令。
当 bash 以"交互式 shell" 启动时,会设置 **`PS1` 环境变量**,且特殊**环境变量 `$-` 的值中会包含 `i` 字符**。
### 交互式 shell 加载的配置文件
交互式 shell 在启动时,会**直接加载** "**==bash shell 配置文件==**":
- **系统级 bash 配置文件**:**==任何用户==** 每次启动 **交互式 shell** 时都会执行该文件
- `/etc/bash.bashrc` 或 `/etc/bashrc`(取决于发行版)
- 在 Debian 及其衍生系统(如 Ubuntu)使用的是 `/etc/bash.bashrc`;
- 在 Red Hat 和 CentOS 等发行版中使用的是 `/etc/bashrc`。
- **用户级 bash 配置文件**:**==用户个人==** 的 bash 配置文件
- `~/.bashrc`
bash 配置文件在每次启动 "**==交互式 shell==**" 时都保证会被执行,但具体调用方式会有所差异:
- 对于**交互式登录 shell**,
- 在 `/etc/profile` 中包含对 `/etc/bash.bashrc` 的加载。
- 在 `~/.profile` 中包含对 `~/bashrc` 的加载。
- 对于**交互式非登录 shell**:
- 在 Debian/Ubuntu 系列中 shell **首先执行 `/etc/bash.bashrc`,再执行 `~/.bashrc`**。
- 在 Red Hat 和 CentOS 中 shell 将**直接执行 `~/.bashrc`**,而在后者**中包含对 `/etc/bashrc` 的加载**。
> [!info] **Ubuntu 下的 "bash shell 配置文件"**
>
> **两个配置文件均只对 "==交互式 shell==" 有效**,**对于 "非交互式 shell" 不执行任何操作**。
>
> (1)`/etc/bash.bashrc` 文件
>
> ![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-FD4CE74AA58C23D9A36EEF994298FCAE.png]]
>
> (2) `~/.bashrc` 文件
>
> ![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-39AC8913FC56E85E3BC4D9330D19188F.png]]
>
>
>
参见:[What's the difference between .bashrc and /etc/bash.bashrc? - Ask Ubuntu](https://askubuntu.com/questions/815066/whats-the-difference-between-bashrc-and-etc-bash-bashrc)
![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-1391F8D256BF75C403D56EC27FCF1107.png]]
<br>
# 非交互式 shell
"**非交互式 shell**" 不显示命令行提示符,不与用户进行实时交互,通常用于 **==执行脚本==**,作为**运行 shell 脚本的 shell**。
- 对于 "==**非交互式登录 shell**==",同样将会加载**登录配置文件**。
- 当**通过 bash 解释器并带有选项 `--login` 或 `-l`** 来执行一个 shell 脚本时,**启动的新 shell 实例** 即为**非交互式登录 shell**。
- 对于 "**==非交互式非登录 shell==**",**不会加载任何配置文件**(但会继承父 shell 的环境变量),只会对 **环境变量 `BASH_ENV`** 进行检查,如果存在则其指向的文件将会被读取并执行。
- **当通过 `bash` 或直接以脚本名**来启动一个 shell 脚本(而非以 `source` 或 `.` 命令)时,**启动的新 shell 实例**即为**非交互式非登录 shell**。
![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-D5C9C3878C28B78300477F7AEB45F289.png|568]]
<br><br>
# shell 启动文件配置建议
如果需要**在每次启动新的 bash shell 时都运行特定脚本**,或者**为 shell 会话设置特定属性**,则可以将脚本文件或配置放到 `~/.bashrc` 中。
如果只是需要在每次 "**登录时**"(**启动登录 shell 时**)运行特定脚本,则应当放置到**下列顺序中首个存在的文件**中:

Linux 发行版通常不会包含全部三个文件,每次 **登录 shell** 启动时将按顺序查找上述三者,执行**首个存在的文件**而忽略其余文件。
<br><br>
# 参考资料
# Footnotes