终端和shell , 以及XShell 用ssh命令登陆主机的过程
1. 终端(Terminal)—— 负责输入/输出的进程
-
本质:
- 终端是一个进程(如
gnome-terminal
、iTerm2
、Windows Terminal
),它管理:- 键盘输入(监听用户按键)
- 屏幕输出(显示文字、控制光标)
- 终端设备(如
/dev/pts/0
)
- 在 Linux/Unix 中,终端的底层由 伪终端(PTY) 驱动实现。
- 终端是一个进程(如
-
关键点:
- 终端进程不解析命令,仅负责:
- 将用户的键盘输入传递给 Shell 进程。
- 接收 Shell 进程的输出并显示到屏幕。
- 终端进程不解析命令,仅负责:
2. Shell —— 解析命令的进程
-
本质:
- Shell 也是一个进程(如
/bin/bash
、/bin/zsh
),它:- 从终端进程接收输入(如
ls -l
)。 - 解析命令(处理变量、通配符、管道等)。
- 通过系统调用如
fork()
+exec()执行操作
。 - 将结果返回给终端进程显示。
- 从终端进程接收输入(如
- Shell 也是一个进程(如
-
关键点:
- Shell 可以独立于终端存在(例如执行脚本时),但交互式使用需要终端提供输入/输出环境。
使⽤ XShell 和ssh命令登陆主机的过程
3. 本地 Windows 端的流程
(1) 用户在终端(如 PowerShell/CMD)输入命令
bash
ssh user@192.168.1.100
- 终端进程(如
conhost.exe
或 Windows Terminal)将输入传递给 Windows Shell进程(如cmd.exe
或powershell.exe
)。
(2) Windows Shell 调用 ssh.exe
进程
- Windows 10+ 内置 OpenSSH 客户端(
ssh.exe
),Shell 会启动一个 SSH 客户端进程:bash
ssh.exe -t user@192.168.1.100
- 如果使用第三方工具(如 PuTTY),则启动的是
putty.exe
进程。
(3) SSH 客户端发起 TCP 连接
- 客户端向目标服务器(
192.168.1.100
)的 22 号端口发起加密的 TCP 连接。 - 底层通过 Windows 的 Socket API(如
connect()
)完成网络通信。
4. 远程 Linux 端的流程
(1) SSH 服务端(sshd
)监听连接
- Linux 服务器上运行的
sshd
守护进程(默认监听 22 端口)接受连接请求。 - 通过
fork()
创建一个子进程处理该连接(避免阻塞主进程)。
(2) 身份验证
- 服务端与客户端协商加密算法(如 AES-256),然后验证用户身份:
- 密码认证:客户端发送加密后的密码,服务端校验
/etc/shadow
。 - 公钥认证:客户端使用
~/.ssh/id_rsa
私钥签名,服务端校验~/.ssh/authorized_keys
。
- 密码认证:客户端发送加密后的密码,服务端校验
(3) 启动远程 Shell
- 认证成功后,服务端调用
exec()
启动用户的默认 Shell(如/bin/bash
): -
bash
exec("/bin/bash", "-i"); # 交互式 Shell
sshd
的子进程通过exec()
替换为 Shell 后,Shell 会继承原子进程的所有资源(包括套接字、文件描述符、伪终端 PTY)。此后,通信直接发生在 SSH 客户端和远程 Shell 之间
5. 本地进程关系与通信链
当你在本地终端输入 ssh user@host
时,进程的层级关系如下:
终端进程(如 gnome-terminal)
└── 本地 Shell 进程(如 bash)└── SSH 客户端进程(如 ssh)
- 终端:负责显示界面、捕获键盘输入。
- 本地 Shell:解析命令,启动 SSH 客户端。
- SSH 客户端:与远程服务器通信。
5. 本地终端输入如何传递到 SSH 进程?
关键机制:标准输入/输出(stdin/stdout)的继承
-
终端控制输入/输出
- 终端的输入(键盘)和输出(屏幕)默认绑定到 标准流(stdin/stdout/stderr)。
- 当终端启动 Shell 时,Shell 会继承终端的标准流。
-
Shell 启动 SSH 客户端
- Shell 通过
fork()
+exec()
启动 SSH 客户端进程。 - SSH 客户端会继承 Shell 的文件描述符(包括 stdin/stdout/stderr),因此:
- SSH 的
stdin
来自终端的键盘输入。 - SSH 的
stdout
输出到终端的屏幕。
- SSH 的
- Shell 通过
-
SSH 客户端独占通信
- 一旦 SSH 客户端启动,本地 Shell 会挂起(等待 SSH 退出),不再处理输入。
- 此后,终端的所有输入直接传递给 SSH 客户端(因为 SSH 继承了终端的 stdin)。