使用 Term 时最常遇到的问题和解决办法。
通常有两个原因。一个是切到后台。切走时,Term 会向系统申请一小段后台时间,最长 70 秒,在这段时间内回来,会话原封不动,接个电话、回条消息都不会断线。系统实际给的额度可能更短(它自己的上限约 3 分钟,低电量时约 1 分钟),你一回到前台,这段后台时间就立即结束。超过这段时间之后,为了省电,HarmonyOS 会挂起长时间停留在后台的应用,连接随之关闭:SSH 会话断开,里面正在运行的程序也会停止。
另一个原因是网络变了,这一种连切后台都不需要,Term 可以一直好好地摆在屏幕上。普通 SSH(telnet 也一样)是一条 TCP 连接,两端各钉死在一个 IP 地址上:手机从 Wi-Fi 切到 5G、走出路由器的覆盖范围、进电梯或者过隧道,地址一变、或者包发不出去,这条连接就没了,哪怕你全程都看着它。而且往往没有任何提示,直到你敲下一个键,发现没有回显。mosh 是唯一扛得住这个的传输方式:它走 UDP,认的是会话而不是地址,换到新网络上会自己接着跑。
下面是四种办法。前三种是让会话不断:从最简单到最稳健;第四种是万一还是断了,怎么回到原来的地方。
只要 Term 在屏幕上,会话就一直是活的。把它放进悬浮窗或分屏,它就算在前台:你可以同时用别的应用而不掉线。
最稳的做法是:服务器上跑 tmux 或 zellij,连接用 mosh。mosh 能扛住网络切换并自动重连,复用器则让程序在服务器上持续运行:随时断开、随时回来,原地接着干。
sudo apt install tmux(Debian/Ubuntu)或 sudo dnf install tmux(Fedora)。tmux new -s work。tmux attach -t work,一切保持原样。mosh-server),漫游切换 Wi-Fi / 蜂窝也不断线。# 新建命名会话 tmux new -s work # 重连之后挂回去 tmux attach -t work
默认配置的 tmux 会悄悄吞掉不少 Term 能做的事(内嵌图片、剪贴板、带修饰键的组合键),而且它不会报错,只是没反应。所以值得配一次。我们用来测试 Term 的那份配置有专门一页,每一行都有注释,还有一键复制整份的按钮。其中有一行正是为这一节写的:tmux 发剪贴板 OSC 52 时不填目标,而 mosh 只转发 52;c; 这一种写法,没有那行 terminal-overrides 去纠正,你在 tmux 里复制的内容只会落进 tmux 自己的粘贴缓冲区,根本出不了服务器。其中两行跟图片有关的设置,本页下面还有一节专门讲。
逐行讲这份配置:我们在用的 tmux 配置
耗时任务别挂在终端前台上跑:丢进 tmux/zellij,或者用 nohup … &。即使应用断连,任务也会在服务器上跑完,之后重连回来检查结果即可。
# 脱离终端后台运行,输出写入 out.log nohup ./long-task.sh > out.log 2>&1 & # 重连后查看进度 tail -f out.log
前面三种都是尽量不让会话断。这一种承认它总有断的时候(手机被挂起、网络断了),但仍然把你送回原来的工作现场。给主机设置一条启动脚本,让它接上多路复用器,脚本下方就会出现自动恢复会话开关:打开之后,随应用一起被杀掉的标签页会在下次启动时重新打开,在后台待太久而被断开的标签页会在你切回来时自动重连。
这里没有任何东西被“复活”,这一点值得说清楚:SSH 连接一旦断开就是断了,服务器那边没有会话在等你。Term 做的是重新连接,真正保住你工作的是多路复用器,启动脚本负责把你重新放回它里面。所以只有当脚本确实会接上点什么,开关才会出现;只对 SSH 提供,默认关闭,而你自己关掉的标签页不会被找回来。
main。tmux new -A -s main(没有就新建、有就接上),zellij 用对应的 attach 命令。第一次连接和之后每一次都用同一行。# tmux:没有就新建,有就接上(zellij 用户用对应 attach 命令) tmux new -A -s main # zellij zellij attach -c main
想了解更多:会自己回来的 SSH 会话:什么能恢复、什么不能
建一个命名会话,Term 就会发现你在跑 tmux,然后把软键盘上方的按键栏换成一套 tmux 专用键:esc、^B 前缀、四个方向键,以及一批一按就发出去的前缀组合。识别靠的是 Shell 集成上报的命令(默认开启),所以别把它关掉。
tmux new -s work。^B[ 进入复制模式(回看历史就靠它)、^Bz 放大当前窗格、^B% 与 ^B" 分屏、^Bc 新建窗口、^Bn / ^Bp 切换下一个 / 上一个窗口、^Bw 窗口列表、^Bd 脱离;^C 和 ^R 也在,毕竟底下还是个 shell 提示符。ctrl:它会为下一个按键挂上 Ctrl 修饰(alt、shift 同理)。^Bd 脱离:会话和里面正在跑的程序都留在服务器上。tmux attach -t work 挂回去,一切保持原样。
tail -12 ~/logs/app.log;最下面那条深色行是 tmux 自己的状态栏,左边是会话名 work,中间是窗口 1:bash*,右边是时钟。顶部导航栏写着的 tmux new -s work 就是 Shell 集成上报的命令,按键栏正是据此切到 tmux 键集的。
^Bd 之后,tmux 打出 [detached (from session work)] 并把 shell 还给你;下一行的 tmux attach -t work 会把整个会话原样接回来。先在服务器上装好 mosh,Term 实际需要的是里面的 mosh-server。然后编辑主机,把连接方式选成 Mosh;应用里那行提示已经把话说清楚了:登录仍然走 SSH,之后才把会话交给 UDP。所以服务器一侧还要放行 UDP 60000–61000;如果只开放了少数几个 UDP 端口,也可以在主机编辑页把 mosh 钉在这几个端口上。连上之后,切换 Wi-Fi / 蜂窝、信号中断都不会掉线,会话会自己重连,上面那条后台挂起的规矩,对 mosh 不适用。
UDP 60000–61000,不特别指定的话,mosh 会在这个范围里自己挑一个端口。只放行了特定端口的话,就在连接方式里的「UDP 端口或范围(可选)」填上:单个端口(60000)或一段范围(60000:61000);留空就是自动挑。ps -o args= -p $PPID,shell 的父进程应该是 mosh-server,而不是 sshd。
# 安装 mosh:Term 要的是里面的 mosh-server sudo apt install mosh # Debian / Ubuntu sudo dnf install mosh # Fedora / RHEL sudo pacman -S mosh # Arch sudo zypper install mosh # openSUSE sudo apk add mosh # Alpine brew install mosh # macOS (Homebrew) sudo pkg install mosh # FreeBSD # 确认 shell 的父进程真的是 mosh-server ps -o args= -p $PPID
ps -o args= -p $PPID 回答的是 mosh-server new -s -c 256 …:shell 的父进程是 mosh-server,不是 sshd,会话确实跑在 UDP 上。顶部导航栏也写着 Sandbox (mosh)。想再深一步:Mosh 进阶设置:端口、会话超时、初始化脚本
因为 mosh 是直接重绘屏幕,而不是逐行传输,根本没有历史可以给 Term 往上翻。这是 mosh 的设计,不是 Term 的限制。想回看,就在服务器上跑 tmux 或 zellij,用它自己的回滚:在 tmux 里就是复制模式,也就是按键栏上的 ^B[(见上面 tmux 那一节)。应用里也会在原地说同一件事,首次连上 mosh 时的提示卡,以及在 mosh 会话里第一次上滑时弹出的提示。
会。关掉 mosh 标签页时,Term 会发出 mosh 的关闭数据包,结束服务器上的那个会话;万一这些包没能送到,它还会再用 SSH 连回去,把遗留的 mosh-server 收掉,基本不会在主机上留下孤儿进程。想稍后回来,就别关标签页。如果这份工作必须活得比标签页更久,那正是 tmux/zellij 的用处:在 mosh 会话里跑 tmux/zellij,关掉标签页也只是脱离而已。
mosh 先用 SSH 登录,再把会话交给 UDP,这两条报错分别对应其中一段出了问题,Term 会直接告诉你是哪一段。失败画面下方保留着原始错误和它的 E_ 代码(提 bug 时用得上),并给出编辑主机和重试两个按钮。
UDP 60000–61000。能,但 tmux.conf 里要加两行。Term 原生解码 sixel、kitty 图形协议和 iTerm2 的 imgcat(OSC 1337)(PNG、JPEG 以及 GIF 的第一帧),并把图像合成在文字下层。要穿过 tmux,图像走的是 kitty 的 Unicode 占位符方案:图像 id 藏在单元格的真彩色前景色里。所以 tmux 一要放行这段转义序列,二要在内部保持真彩色,少了第二条,tmux 会把带 id 的颜色降到 256 色,id 被改坏,图也就废了。这两行都需要 tmux 3.3a 或更新的版本,版本太旧的话,tmux 启动时只会报 “unknown option”,图片就悄无声息地出不来了。
# 放行图像的转义序列 set -g allow-passthrough on # 在 tmux 内保持真彩色,否则图像 id 会被改坏 set -as terminal-features ",*:RGB"
mosh 会话不受影响,它本来就能在后台存活并自动重连,所以后台警告对它不适用。应用内也有同样的说明:主机页面的后台会话警告横幅 → 点开「保持会话在线」帮助页。
参考: mosh.org · tmux 入门 · zellij · GNU screen · nohup(1)