%% # 纲要 > 主干纲要、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` 环境变量: ![image-20231102172727294|696](_attachment/02-开发笔记/11-Linux/shell%20相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-7BCF68602888090C215FF19D141F144E.png) > [!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` 文件。 ![img|588](_attachment/02-开发笔记/11-Linux/shell%20相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-348764A70F89E93A27CAE78CCDC3A4F9.jpg) ##### `~/.pam_environment` 文件 用户级 PAM 配置文件。 <br><br> # 初始化配置文件的加载顺序 ![[_attachment/02-开发笔记/11-Linux/shell 相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-79F614CF528373C19D8721B006AA4160.png|525]] 以 Ubuntu 为例,对**环境变量相关文件**的加载包括两部分: - **PAM 模块**对 **PAM 文件**的加载 ![image-20231102202504707|375](_attachment/02-开发笔记/11-Linux/shell%20相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-B66FE4D95FC6FA3247F59BD710D30095.png) - **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` 中 ![image-20231102231301287|625](_attachment/02-开发笔记/11-Linux/shell%20相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-FC6DD2196D54A1AB5E27716BDB385D20.png) --- <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** ![image-20231101233746679|475](_attachment/02-开发笔记/11-Linux/shell%20相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-94AFE705FDDE1E776A42B9CACDAE0840.png) - 通过终端窗口(GNOME-terminal)打开的 shell:**交互式非登录 shell** > 许多现代 Linux 发行版使用图形登录屏幕。当用户通过图形界面登录后,然后打开终端窗口(如 gnome-terminal, konsole 等),此时启动的 shell 实例是一个**交互式非登录 shell**。这是因为**图形会话管理器已经作为登录 shell 启动**,并处理了相关的登录脚本。此后在此会话中启动的所有终端都被认为是非登录 shell。 > ![image-20231101232700246|450](_attachment/02-开发笔记/11-Linux/shell%20相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-5F9C27FDB632A9568AB1E0F78B7323DD.png) - 使用 `su -` 或者 `su -l ` 命令切换用户时,启动 **交互式登录 shell**。 ![image-20231102154914556](_attachment/02-开发笔记/11-Linux/shell%20相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-1C57F3EDB5187C18A7A3CCE20B5913A5.png) - 使用 `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 时**)运行特定脚本,则应当放置到**下列顺序中首个存在的文件**中: ![image-20240116122521118|144](_attachment/02-开发笔记/11-Linux/shell%20相关/Linux-环境变量与配置文件.assets/IMG-Linux-环境变量与配置文件-42C653A107DD45EF7CAAE41B5E382CF3.png) Linux 发行版通常不会包含全部三个文件,每次 **登录 shell** 启动时将按顺序查找上述三者,执行**首个存在的文件**而忽略其余文件。 <br><br> # 参考资料 # Footnotes