跳到正文

打开终端后发生了什么 ​

终端窗口里跑着的 Shell,并不是直接连着你的键盘和屏幕。中间还有伪终端和行规程。

数据通路 ​

masterslavestdout按键终端模拟器行规程Shell
  • 模拟器申请一对 pty:master 和 slave
  • Shell 的 fd 0/1/2 接在 slave 上
  • 模拟器从 master 读字节,画到窗口
检查方式命令
Linux fdls -l /proc/$$/fd
macOS fdlsof -p $$
终端设备tty

行规程 ​

按键行为
Ctrl-C前台进程组收到 SIGINT
Ctrl-\SIGQUIT
Ctrl-ZSIGTSTP,挂起
Ctrl-D缓冲区为空时表示 EOF
回车把整行交给 Shell

关键概念是前台进程组:终端驱动不认识“当前程序”,只把信号发给前台组,组里所有进程一起收到。

bash
stty -a     # 查看模式
stty raw    # 原始模式
stty sane   # 恢复正常

raw 模式与全屏程序 ​

  • vim、less、tmux 自己关闭回显和行编辑
  • 按键直接由程序处理,光标靠转义序列重绘
  • 退出时恢复终端;恢复失败用 reset
  • script -q session.log 可以录下整次会话

关闭终端 ​

手段效果
直接关窗口会话收到 SIGHUP,后台任务退出
nohup cmd &忽略 SIGHUP,输出进 nohup.out
disown从作业表移除,不再收挂断
setsid新会话,脱离控制终端
tmux会话独立存在,可重新接上

ssh host cmd 默认不分配 tty,所以远端程序会关掉颜色和交互;需要时用 ssh -t。