控制台和终端
疑问来自内核调试,无论我如何调整 printk 的日志级别,都不能在我的命令行界面中看到调试信息。对这个反常现象的追究,让我认识到了控制台和终端的区别。
控制台 (Console)
控制台
是内核的亲儿子。本质计算机的物理管理接口,直接连接系统主板(如服务器前面板的 VGA + 键盘接口)。现代 Linux 将其虚拟化为虚拟控制台(Virtual Console)。分为:
- 物理控制台:比如嵌入式 Linux 通常将一个串口作为控制台,称为串口控制台
- 虚拟控制台:由 Linux 内核直接管理,系统启动时自动创建 (tty1~tty6)。通过
Ctrl+Alt+F1
至Ctrl+Alt+F6
切换,虚拟控制台的输入/输出设备是直连硬件的(比如键盘接口和视频接口)。
控制台才可以接收所有内核消息(如启动日志、内核崩溃信息 Oops),终端则不可以。这就是我在命令行中看不到内核调试信息的原因,我的命令行实际上是一个模拟终端。当我切换到虚拟控制台 (Ctrl+Alt+F1)后,才看到实时显示的内核调试信息。
终端 (Terminal)
终端
是用户的助手。为用户提供命令行交互环境的软件抽象,早期是物理设备(如 VT100 终端),现代由软件模拟(如 xterm、GNOME Terminal)。分为:
- 物理终端:真实的物理设备,比如 VT100 终端,它通过一根串口线与大型机相连,目前已淘汰。
- 模拟终端:在图形用户界面(GUI)环境下运行的应用程序(比如:
/dev/pts/2
),提供了类似传统终端的功能。 - 网络终端:通过 SSH/Telnet 远程访问
模拟终端和网络终端都是通过 伪终端 (Pseudo Terminal) 实现的,所以我通过 ssh 登陆的终端类型为 pts/0
,其中 p 就是 Pseudo。
总结
特性 | 控制台 (Console) | 终端 (Terminal) |
---|---|---|
物理起源 | 计算机本机的物理控制面板(直接连接硬件) | 远程输入输出设备(如电传打字机 VT100) |
现代实现 | 内核直接管理的虚拟设备 (/dev/ttyN ) |
软件模拟的交互环境(终端模拟器、SSH) |
数量限制 | 有限(通常 6 个:tty1~tty6) | 理论上无限(通过伪终端 PTS 动态创建) |
访问方式 | 物理键盘 + 显示器(如 Ctrl+Alt+F1) | 通过网络或 GUI 终端程序访问 |
系统级作用 | 内核消息输出、单用户模式修复 | 用户交互、程序运行 |
依赖图形界面 | 完全独立(甚至在图形崩溃时仍可用) | 可能依赖网络/GUI(如 Gnome Terminal) |
设备路径 | /dev/ttyN (N=1~6) |
/dev/pts/<ID> (动态分配) |
登陆 Shell 和普通 Shell
定义
- 登陆 shell (Login Shell):登陆 系统时启动的第一个 shell 。一般通过以下途径启动:
- 系统登陆界面
- 通过 ssh 远程登陆 (也要先登陆)
- 在命令行中显示指定
--login
选项 启动 shell,比如:bash --login
- 普通 shell (Non-Login Shell):登陆系统后,在一个会话中再启动的 shell。一般通过以下途径启动:
- 图形界面中的终端模拟器
- 在现有 shell 中直接启动新的子 shell,比如通过 bash 命令
- 运行 shell 脚本
为什么要区分不同 shell
因为不同的 shell 加载的配置文件不同 ,登陆 shell 进行耗时的全面初始化,普通 shell 在此基础上只需设置自己的交互配置,在登陆 shell 的基础上进行个性化定制。
- 登陆 shell 加载的配置:先加载
系统级
登陆配置文件,然后加载用户级
登陆配置文件。/etc/profile
:系统级登陆 配置文件,作用于所有用户。- 如果使用
bash
作为默认 shell,它会依次加载:/etc/profile
→/etc/bash.bashrc
- 应避免直接修改
/etc/profile
或/etc/bash.bashrc
,自定义配置放入 /etc/profile.d/custom.sh
- 如果使用
~/.profile
:用户级登陆 配置文件。- 如果使用
bash
作为默认 shell,它会依次加载:~/.bash_profile
→~/.bash_login
→~/.profile
- 如果使用
bash
作为默认 shell,在~/.profile
中会调用~/.bashrc
,
- 如果使用
- 普通 shell 加载的配置:
- 使用
bash
作为默认 shell:加载~/.bashrc
- 普通 shell 继承父进程的环境变量,这意味着所有普通 shell 都会继承登陆 shell 加载的配置环境。
- 使用
登陆 shell 会加载普通 shell 的配置吗?
会。
比如使用 bash
作为默认 shell,在加载用户级登陆配置文件 ~/.profile
中,会调用 ~/.bashrc
:
bash
# 如果 ~/.bashrc 存在且当前 Shell 是 Bash,则加载它
if [ -n "$BASH_VERSION" ] && [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
如何确认是哪种 shell ?
使用命令: echo $0
,以 bash 为例,
- 返回
-bash
:输出以 - 开头,是登陆 shell - 返回
bash
:普通 shell
Ctrl+C
和 Ctrl+Z
的区别
以 bash 为例:
Ctrl+Z
:只是把前台进程暂停(SIGTSTP,送入后台、挂起),并不会关闭文件或释放资源 。用fg
可以把挂起进程恢复到前台。Ctrl+C
:终止前台进程(SIGINT),这样发送SIGINT
信号可中断并退出。- 有些应用可能不支持
Ctrl+C
,比如less
,退出是按q
键。
其它控制键
- 查看当前终端的快捷键设置:
stty -a
(Set Telttype,all) Ctrl+D
:发送文件结束符(EOF),关闭输入流Ctrl+\
:强制退出并生成 core (SIGQUIT)
Shell 词法结构
逐行 读取输入,并将输入拆分 为一个个的单词(words,这里跟英语中的"单词"含义不同。英语中"单词"是具有独立意义的最小单位,shell 中的"单词"只不可分割的字符序列。比如 last_year,英文中不是一个合法单词,但在 shell 中则是),拆分依据是:
空白字符
:空格和制表符操作符
:对 shell 有特殊意义的字符序列
操作符有两类:控制操作符
和 重定向操作符
- 控制操作符:
&
、&&
、(
、)
、;
、;;
、|
、||
、<newline>
(换行符) - 重定向操作符:
<
、>
、>|
、<<
、>>
、<&
、>&
、<<-
、<>
Shell 引用
某些字符或单词在 shell 中有特殊含义,比如空白字符、操作符或关键字,引用
(quoting) 用来消除它们的特殊含义。引用有三种:
- 成对的双引号
- 反斜杠:消除单个字符的特殊含义,换行符除外。出现在换行符前的反斜杠被视为
续行符
(continuation) - 成对的单引号:消除单引号包裹的所有字符的特殊含义,单引号本身除外,所以无法在成对的单引号中包含单引号