Shell 是 Linux 系统中与用户交互的关键工具,它充当了用户与操作系统之间的桥梁。通过 Shell,用户可以输入命令并控制系统的各种操作。在使用 Shell 时,它的运行方式或启动方式对于我们如何与系统进行交互至关重要。根据启动的不同方式,Shell 主要有四种运行模式:交互式的登录 Shell、交互式的非登录 Shell、非交互式的登录 Shell 和非交互式的非登录 Shell。理解这些不同的启动方式将帮助我们更好地管理和操作 Linux 系统。
一、Shell 运行方式的分类
-
交互式的登录 Shell
- 在启动时,Shell 需要用户提供用户名和密码进行登录。这种方式通常是在控制台或通过 SSH 登录时使用。
- 交互式意味着用户可以在 Shell 中输入命令并得到即时反馈。
-
交互式的非登录 Shell
- 这种方式通常是在打开一个新终端窗口时发生的。虽然 Shell 可以交互,但它并没有经过登录过程,因此不会加载登录时需要的配置文件(例如
.bash_profile)。 - 常见的情况是在图形用户界面的终端窗口中打开一个 Shell。
- 这种方式通常是在打开一个新终端窗口时发生的。虽然 Shell 可以交互,但它并没有经过登录过程,因此不会加载登录时需要的配置文件(例如
-
非交互式的登录 Shell
- 这种方式比较少见,一般是在自动化脚本执行时使用。Shell 通过某些方式模拟登录过程,且不需要用户交互。
- 即使它是登录 Shell,它也不会提供即时反馈,因为它并不接受用户输入。
-
非交互式的非登录 Shell
- 这种模式下,Shell 不会与用户交互,也不执行登录步骤。通常在批量任务或脚本中使用。它不会加载登录时的配置文件,也不会显示任何提示符。
- 常见的情况是在后台执行脚本时。
二、如何判断 Shell 是交互式的
判断一个 Shell 是否是交互式的有几种常见方法。以下是两种简单的判断方法:
1. 查看 $- 变量的值
$- 变量保存了当前 Shell 的标志,如果其中包含字母 i,则表示该 Shell 是交互式的。
-
实例 1 在 CentOS GNOME 桌面环境自带的终端下:
echo $-输出:
himBH包含
i,因此是交互式 Shell。 -
实例 2 在 Shell 脚本文件中:
cat test.sh #!/bin/bash echo $-运行:
bash ./test.sh输出:
hB不包含
i,因此是非交互式 Shell。
2. 查看 $PS1 变量的值
$PS1 变量控制 Shell 的提示符。若该变量非空,则表示该 Shell 是交互式的,否则是非交互式的。
-
实例 1 在 CentOS GNOME 桌面环境自带的终端下:
echo $PS1输出:
[\u@\h \W]\$非空,表示交互式 Shell。
-
实例 2 在 Shell 脚本文件中:
cat test.sh #!/bin/bash echo $PS1运行:
bash ./test.sh输出:
(空值)空值,表示非交互式 Shell。
三、如何判断 Shell 是否是登录式的
判断 Shell 是否是登录式的也非常简单,可以通过 shopt 命令查看 login_shell 选项的值。如果 login_shell 为 on,则表示当前 Shell 为登录式;如果为 off,则表示为非登录式。
-
实例 1 在 GNOME 桌面环境中查看登录 Shell 选项:
shopt login_shell输出:
login_shell off -
实例 2 在虚拟终端中,输入用户名和密码登录后:
shopt login_shell输出:
login_shell on -
实例 3 在 Shell 脚本文件中查看:
cat test.sh #!/bin/bash shopt login_shell运行:
bash ./test.sh输出:
login_shell off
四、常见的 Shell 启动方式
了解如何启动 Shell 是区分不同运行模式的关键。以下是几种常见的启动方式:
-
通过 Linux 控制台或 SSH 登录 Shell(交互式的登录 Shell) 当通过控制台登录或通过 SSH 远程登录时,Shell 会处于交互式的登录状态。这时会加载系统的登录配置文件,并允许用户进行交互式操作。
echo $PS1; shopt login_shell输出:
[\u@\h \W]\$ login_shell on -
通过执行
bash命令启动 Shell(默认非登录 Shell) 执行bash命令时,Shell 会是非登录式的。如果添加--login或-l选项,则会变成登录式 Shell。# 在 Shell 脚本中: cat test.sh #!/bin/bash echo $-; shopt login_shell执行:
bash -l ./test.sh输出:
hB login_shell on -
子 Shell 启动(继承父 Shell 的属性) 使用
()包围的组命令或命令替换启动子 Shell 时,子 Shell 会继承父 Shell 的交互式和登录式属性,但它并不会重新加载配置文件。bash (echo $PS1; shopt login_shell)输出:
[\u@\h \W]\$ login_shell off -
远程执行命令时(非交互非登录式 Shell) 当通过 SSH 执行远程命令时,Shell 会是非交互式且非登录式。
ssh localhost 'echo $PS1; shopt login_shell'输出:
login_shell off -
桌面环境下打开终端(交互式的非登录 Shell) 在 Linux 桌面环境下打开终端时,通常会启动一个交互式的非登录 Shell。此时,Shell 允许用户进行交互,但不会加载登录配置文件。
总结
Shell 是 Linux 系统中非常重要的一个工具,通过不同的启动方式,用户可以灵活地选择交互模式或脚本执行模式,满足不同的工作需求。掌握 Shell 的四种运行方式(交互式与非交互式、登录式与非登录式),可以帮助系统管理员或开发者更高效地与 Linux 系统进行交互。
补充:TAB 补全与 Shell 交互模式的关系
很多人认为按 TAB 键自动补全命令与 Shell 是否为交互式有关,但实际上,TAB 补全是由 readline 库提供的功能,与 Shell 交互模式并无直接关系。readline 负责处理用户输入,并提供编辑和补全功能,无论 Shell 是交互式还是非交互式,都可以通过特定方式启用或禁用 readline 的自动补全功能。例如,在非交互式 Shell 运行时,readline 可能不会生效,但这并不意味着 Shell 本身无法补全,而是因为 readline 仅在特定交互环境下被调用。
如果你在交互式 Shell 中发现 TAB 补全无法使用,可以检查 readline 配置,或者确保 Shell 启用了 set -o vi 或 set -o emacs 这样的输入模式,以获得更好的命令行编辑体验。
原文 https://blog.csdn.net/2301_79518550/article/details/145840976