SSH 一断,跑了半小时的命令就没了?用 tmux 把任务和连接拆开
远程运维最让人心疼的事故,往往不是命令写错,而是连接先断了:一条跑了四十分钟的数据迁移,SSH 在第三十八分钟闪断,重连之后进度清零,只能从头再来。问题不在命令本身,而在命令的宿主——它挂在那个 SSH 会话下面,会话一断,系统发 SIGHUP,进程跟着一起走。tmux 解决的就是这个宿主问题:把进程挪进一个独立于 SSH 的常驻会话,SSH 只是它的一块屏幕,屏幕碎了进程不死。
一、会话、窗口、面板:三层结构一次说透
tmux 的结构是会话(session)> 窗口(window)> 面板(pane)。断线重连保住的是会话,窗口和面板都在会话里面,所以“保住进程”实际上就是“进程跑在一个没被杀掉的会话里”。
新建一个带名字的会话:tmux new -s ops。列出所有会话:tmux ls。接入已有会话:tmux attach -t ops。会话里的进程哪怕你关掉终端、合上笔记本、切换 Wi-Fi,都一直在后台跑,重连后 attach 回去,输出原样保留。
二、每天只用记住两个动作:detach 与 attach
所有操作都走一个前缀键 Ctrl+b:先按 Ctrl+b,松开,再按功能键。最常用的两个:
Ctrl+b d:detach,回到外层 shell,会话在后台继续跑。
tmux attach -t ops:attach 回 ops 会话,现场原样恢复。
还有一条更顺手的:tmux new -A -s ops,一条顶两条,会话存在就 attach,不存在就新建。把它写进常用命令里,登录服务器后的第一件事就是先进 tmux,再开始干活。
一个容易踩的坑是直接关终端窗口:在 SSH 场景下这等于发 SIGHUP,反而可能把会话里的前台进程杀掉。养成“先 detach 再关窗口”的习惯,能省下大量重跑的时间。
三、一个终端当几个用:窗口与分屏
一个会话里可以开多个窗口(Ctrl+b c 新建,Ctrl+b n/p 切换),每个窗口又能再分面板(Ctrl+b % 左右分,Ctrl+b " 上下分)。排查问题时一边 tail 日志、一边跑命令,不用来回切换终端。
日志刷屏时 Ctrl+b z 可以把当前面板临时放大,看完再按一下回到原布局。复制模式(Ctrl+b [)可以回滚历史输出、翻找早先的报错,再也不用担心输出滚过去就找不回来。
四、tmux 保护什么、不保护什么
tmux 只保护会话里跑的进程。服务器重启,tmux server 跟着退出,会话自然全部不存在——这不是故障,重新 tmux new 即可。所以分工要划清:交互式的长任务(迁移、编译、升级)放 tmux;真正的长期任务交给 systemd 服务或 nohup + setsid,不要只依赖 tmux。
同样,已经跑起来的长命令如果没放进 tmux,SSH 眼看要断了,事中补救只有 disown 配合 nohup 这一档手段,而且只对还没产生终端输出的场景勉强有效,交互式程序救不回来。正确姿势永远是开跑之前先 tmux new -s job 再执行。
五、两个人同时看一个会话
tmux 天然支持两个 SSH 连接接同一个会话:两个人用同一个系统账号 tmux attach -t ops,画面完全同步。一个人操作,另一个人在边上实时看,排查线上问题时非常好用。注意共享会话里的操作是不可分辨的,别在里面做互相不知道的破坏性操作。
小结
tmux 的价值可以用一句话压缩:把“进程的生死”和“连接的生死”拆开。做到这一件事,SSH 闪断只是换块屏幕,四十分钟能跑完的迁移再也不用从零开始。规则也很简单:所有超过五分钟的命令,都放到命名会话里跑。
(本文为个人运维实践记录。)
- 点赞
- 收藏
- 关注作者
评论(0)