跳过正文
  1. 笔记/
  2. Linux/

Shell、Terminal、TTY/PTY 的区别

·1962 字·4 分钟· loading · loading · · ·
ICE345
作者
ICE345
CS Student | System | Linux | OCaml

Shell、Terminal、TTY/PTY 的区别
#

简单来说就是如下关系:

 ↓ 输入命令
终端模拟器 Terminal Emulator
 ↓ 提供一个“终端窗口”
TTY / PTY
 ↓ 传递输入输出
Shell
 ↓ 解释命令并调用程序
操作系统内核 / 程序

1. Shell 是什么?
#

Shell 是命令解释器。

你输入:

ls -l
cd Desktop
python main.py

真正理解这些命令并执行的是 shell

常见 shell 有:

sh      最早期的 Unix shell
bash    Linux 中很常见
zsh     macOS 现在默认使用
fish    更现代、交互体验更好
powershell Windows 上常见
提示

zsh,bash,fish 这些的不同之处就是它们的语法、功能、交互体验不同,但它们都是 shell,都是命令解释器。

Shell 的作用主要是:

读取你输入的命令
解析命令
执行程序
处理变量、管道、重定向、脚本

例如:

cat a.txt | grep hello > result.txt

这里的 |> 这些符号不是 catgrep 自己理解的,而是 shell 解析的。


2. 终端模拟器是什么?
#

终端模拟器是你看到的那个窗口。

比如:

macOS Terminal
iTerm2
Windows Terminal
GNOME Terminal
Konsole
Alacritty
Kitty
WezTerm

它本身不是 shell。

它的作用是:

显示文字界面
接收键盘输入
显示程序输出
模拟传统终端设备的行为
启动一个 shell

所以你打开 macOS 的“终端”后,里面默认启动的可能是:

zsh

打开 Windows Terminal 后,里面可能启动:

PowerShell

或者:

Ubuntu WSL bash

所以:

终端模拟器 ≠ Shell

终端模拟器是“窗口”,shell 是窗口里面运行的“命令解释器”。


3. TTY 是什么?
#

TTY 原本是 Teletypewriter,电传打字机。

早期计算机没有现代显示器,用户通过一种像打字机一样的设备和计算机交互:

你在机器上打字
计算机返回文字
机器打印出来

这种设备就叫 TTY

后来虽然物理打字机没了,但 Unix/Linux 仍然保留了这个抽象:

TTY = 一种终端设备接口

在 Linux 中你可以看到类似:

/dev/tty
/dev/tty1
/dev/tty2
/dev/pts/0
/dev/pts/1

其中:

/dev/tty1, /dev/tty2 ...

通常是真正的虚拟控制台。

例如在 Linux 里按:

Ctrl + Alt + F1
Ctrl + Alt + F2

进入的黑底登录界面,就是比较接近传统意义上的 TTY。


4. PTY 是什么?
#

你现在在图形界面的终端模拟器里用 shell,通常用的不是传统 TTY,而是 PTY

PTY 全称是:

Pseudo Terminal
伪终端

它是一对虚拟设备:

PTY master  ←→  PTY slave

关系大概是:

终端模拟器
PTY master
PTY slave
shell

终端模拟器通过 PTY master 和 shell 通信。

shell 以为自己连接的是一个真正的终端设备,但其实是一个伪终端。

例如你在终端里运行:

tty

可能看到:

/dev/pts/0

这个 /dev/pts/0 就是一个伪终端设备。


5. 它们之间的关系
#

最常见的情况是:

你打开 iTerm2 / Terminal / Windows Terminal
终端模拟器创建一个 PTY
终端模拟器启动 shell,比如 zsh/bash
shell 绑定到这个 PTY
你输入命令
终端模拟器把输入发给 PTY
shell 收到命令并执行
程序输出返回到 PTY
终端模拟器显示在窗口里

可以画成这样:

+----------------+
|      用户       |
+----------------+
        |
        v
+----------------+
|   终端模拟器     |
| Terminal/iTerm2 |
+----------------+
        |
        v
+----------------+
|   PTY / TTY     |
|  /dev/pts/0    |
+----------------+
        |
        v
+----------------+
|     Shell       |
|   bash / zsh    |
+----------------+
        |
        v
+----------------+
|  命令 / 程序     |
| ls, vim, python |
+----------------+

6. 举个具体例子
#

你打开 macOS Terminal,然后输入:

echo hello

实际发生的是:

1. Terminal.app 打开一个窗口
2. Terminal.app 创建一个伪终端 PTY
3. Terminal.app 启动 zsh
4. 你输入 echo hello
5. zsh 解析这个命令
6. zsh 执行 echo
7. echo 输出 hello
8. 输出经过 PTY 返回 Terminal.app
9. Terminal.app 把 hello 显示出来

7. Shell 和终端最容易混淆的地方
#

很多人说:

打开 shell
打开 terminal
打开命令行

日常说法里经常混着用,但严格来说:

名称本质例子
Shell命令解释器bash, zsh, fish, PowerShell
终端模拟器图形窗口程序Terminal, iTerm2, Windows Terminal
TTY终端设备抽象/dev/tty1
PTY伪终端设备/dev/pts/0
Console控制台,语义较宽Linux 虚拟控制台、系统控制台
CLI命令行界面这种交互方式git、npm、python 命令

8. Terminal、Console、Shell 的区别
#

Terminal
#

更偏向“输入输出设备”或“终端窗口”。

你通过 terminal 和程序交互。

Console
#

历史上指“系统控制台”,通常更接近直接连接到机器的主控输入输出设备。

现在很多时候 console 和 terminal 也会混用。

例如:

browser console
game console
system console

含义会根据场景变化。

Shell
#

是里面真正处理命令的程序。

terminal 负责显示
shell 负责解释命令

9. 为什么 Vim、Top 这类程序需要 TTY?
#

有些程序不是简单输出一行文字,而是需要控制整个屏幕,比如:

vim
top
htop
less
nano
ssh
tmux

它们需要知道:

终端有多少行多少列
光标在哪里
颜色怎么显示
按键是什么
Ctrl+C 怎么处理

这些能力都是通过 TTY/PTY 这套终端接口完成的。

所以你在某些环境里运行命令会看到:

the input device is not a TTY

意思就是:

这个程序需要一个交互式终端,但当前环境没有提供真正的 TTY/PTY。

例如 Docker 里经常见到:

docker run -it ubuntu bash

这里:

-i = interactive,保持标准输入
-t = 分配一个伪终端 TTY

没有 -t,有些交互程序就不好用。


10. SSH 里的关系
#

当你 SSH 到服务器时:

ssh user@server

关系大概是:

本地终端模拟器
本地 ssh 客户端
   ↓ 网络
远程 ssh 服务端
远程 PTY
远程 shell

远程服务器上也会给你分配一个 PTY。

所以你在远程服务器运行:

tty

可能看到:

/dev/pts/3

11. tmux / screen 又是什么?
#

tmuxscreen 可以理解成“终端复用器”。

它们夹在终端模拟器和 shell 中间:

终端模拟器
PTY
tmux
多个 shell / 程序

它们的作用是:

一个终端窗口里开多个会话
断开 SSH 后程序继续运行
分屏
恢复会话

所以 tmux 本质上也会大量使用 PTY。


12. 总结一句话
#

终端模拟器是你看到的窗口;
TTY/PTY 是连接窗口和命令程序的终端设备接口;
Shell 是真正解释并执行命令的程序;
命令行程序通过这套机制和你交互。

最核心的关系是:

用户 → 终端模拟器 → TTY/PTY → Shell → 程序 → 操作系统