screen:那个在SSH断开后依然默默守护你进程的“终端幽灵”
你有没有过这样的经历——深夜跑一个数据库迁移脚本,进度条刚走到 73%,WiFi 一抖,SSH 连接灰了。你猛敲回车、重连、ps aux | grep migrate……结果发现进程没了,日志停在INSERT INTO users VALUES (...)的半截上。再看磁盘,临时表还在,锁没释放,下游服务开始报警。
这不是玄学,是 Linux 终端信号机制的真实代价:默认情况下,SSH 断开会向所有子进程发送SIGHUP(挂起信号),而绝大多数命令行程序并不会主动忽略它。
这时候,screen就像一个提前埋伏好的“终端幽灵”——它不声不响接管了你的 TTY,把你的tail、python train.py、rsync全部塞进一个独立会话里。网络断了?没关系,它的 server 进程照常呼吸;你换台电脑重连?只要一句screen -r,就能回到中断前那一行输出,仿佛时间从未流动。
它不是新潮的云原生工具,没有 YAML 配置、不依赖 Docker,甚至不需要 systemd。但它稳定得让人安心,轻量得几乎隐形,用法简单到两分钟上手,却能在关键时刻保住你整套系统的数据一致性与服务 SLA。
它到底做了什么?别被“复用器”这个词骗了
很多人第一眼看到“终端复用器(Terminal Multiplexer)”,下意识以为是“让多个窗口同时显示在一个终端里”的 GUI 式体验。其实恰恰相反:screen的核心动作,是一次“进程脱钩”。
当你输入screen -S deploy,它干了三件关键的事:
- fork + setsid:创建一个全新的会话(session),让后续所有子进程彻底脱离原始登录 shell 的控制组(process group)。这意味着:
SIGHUP永远传不到它们耳朵里。 - 分配伪终端(PTY):为每个窗口申请一对主/从 PTY(比如
/dev/pts/5),把键盘输入路由到指定窗口,把屏幕输出缓冲到独立内存区。你切窗口时,它只是把不同缓冲区的内容“刷”到当前物理终端上。 - 启动 server-client 架构:
screen本身分裂成两个角色:
-server:驻留后台,绑定到/var/run/screen/S-$USER下的 Unix socket,持续管理所有窗口、缓冲区、日志;
-client:你每次敲screen -r或Ctrl-a c,都是一个轻量 client 连过去发指令——断开的只是 client,server 和里面跑的进程纹丝不动。
所以, <