Hotdry.
systems-engineering

ZMX:轻量级终端会话持久化与 PTY 代理实现

脱离 tmux/screen 开销,利用 ZMX 的 PTY daemon、Unix socket 转发和 libghostty-vt 状态快照,实现高效终端会话 detach/reattach。

在现代开发环境中,tmux 或 screen 等终端多路复用器虽强大,但引入了额外的窗口分割、转义序列翻译等开销,导致原生终端特性(如 Kitty 图形协议、鼠标选择)受阻,甚至颜色渲染异常。ZMX 作为 Zig 语言实现的轻量级方案,专注于单一会话持久化:通过 daemon 代理 PTY,实现 detach/reattach,而不干涉窗口管理(交由 OS WM 处理)。其核心优势在于零配置、多客户端支持和完整终端状态恢复,特别适合 SSH 远程开发场景。

ZMX 的实现机制简洁高效。启动 zmx attach <name> [cmd] 时,daemon 为会话创建 PTY 对,持有 master 端 fd,将 slave 端 exec 命令(如 shell 或 nvim)。每个会话独占 Unix socket /tmp/zmx/<name>,客户端连接后,daemon 使用 poll () 同时监控 PTY fd 和所有客户端 socket,将 stdin 从客户端转发至 PTY,stdout 从 PTY 广播至客户端。同时,daemon 将 PTY 输出镜像馈送 libghostty-vt(Ghostty 终端的 VT 解析器),维护独立终端状态机,包括 scrollback 缓冲、光标位置和 SGR 序列。detach(Ctrl+\)仅关闭客户端 socket,会话进程持续运行;reattach 时,daemon 先 dump VT 快照至客户端 stdout,恢复历史输出与状态,再续传实时数据。此设计确保低延迟(仅 Unix socket 中转)和原生特性直通,无需 tmux 的复杂协议转换。

相较 tmux,ZMX 避免了多层终端嵌套引发的兼容问题。例如,tmux 需额外支持新协议,而 ZMX 直接暴露底层 PTY,支持任意终端仿真器特性。实际测试中,nvim 内 detach 无 bug,支持 autossh 自动重连,且多客户端可同时查看同一会话(虽无输入仲裁)。“zmx 专注于会话持久化,将窗口管理委托 OS WM”(项目哲学)。

部署参数与清单

  1. 环境准备

    • Zig v0.15+(Homebrew/macports 或 zigup)。
    • macOS/Linux(x86_64/aarch64)。
    • PATH 包含 ~/.local/bin
  2. 安装步骤(ReleaseSafe 优化,~5MB 二进制):

    git clone https://github.com/neurosnap/zmx
    cd zmx
    zig build -Doptimize=ReleaseSafe --prefix ~/.local
    # 验证:zmx help
    
    • 阈值:若构建 >10s,检查 Zig 缓存 ~/.cache/zig
    • 回滚:删除 ~/.local/bin/zmx,fallback tmux。
  3. 基本使用清单

    命令 参数 作用 监控点
    zmx attach dev name=dev, cmd = 默认 shell 创建 /attach 会话 ls /tmp/zmx/dev socket 存在
    zmx attach build make -j8 cmd = 长任务 后台构建,断线续观 tail -f /tmp/zmx/logs/build.log
    Ctrl+\ - detach 当前客户端 ps aux | grep zmx-daemon
    zmx list - 列会话 /tmp/zmx/logs/*.log <5MB
    zmx kill dev name 清理会话 + 进程 rm -rf /tmp/zmx/dev*
    • 最佳实践:nvim 用户绑定 <C-\> 至无操作,避免冲突。
    • 超时参数:无内置,poll () 默认阻塞,建议外部 tmux 外层 + ZMX 内层。
  4. SSH 集成配置(~/.ssh/config,重用 ControlMaster):

    Host d.*
        HostName <remote-ip>
        RemoteCommand zmx attach %k
        RequestTTY yes
        ControlPath ~/.ssh/cm-%r@%h:%p
        ControlMaster auto
        ControlPersist 10m
    
    • 用法:ssh d.devssh d.nvim 等,多窗口布局。
    • 增强:alias ash='autossh -M 0 -q',笔记本合盖自动重连。
    • 阈值:ControlPersist 10m 防频繁重连;>20 会话,监控 /tmp/zmx 磁盘。
  5. 监控与运维参数

    • 日志:/tmp/zmx/logs/zmx.log(全局 CLI)、/tmp/zmx/logs/<name>.log(会话,5MB 轮转)。
      • 脚本:watch 'ls -la /tmp/zmx/logs/*.old | wc -l' 清理旧日志。
    • Socket 泄漏(已知 bug):find /tmp/zmx -type s -mtime +1 -delete cron 每日。
    • 性能阈值:poll () 负载 <1% CPU(单核);>10 客户端,考虑 shpool 替代。
    • 安全:/tmp 权限 1777,ZMX 无认证,多用户隔离 session name。

潜在风险与缓解

  • 风险 1:socket 未清理,导致 ls 残留。缓解:kill 前 zmx kill,cron 扫描。
  • 风险 2:无 resize 事件(todo)。缓解:reattach 后手动 resize 或终端自动 ioctl。
  • 扩展:Shell 提示集成 ZMX_SESSION:fish 示例显示 [dev] 前缀。
    functions -c fish_prompt _orig_fish_prompt
    function fish_prompt
        if set -q ZMX_SESSION; echo -n "[$ZMX_SESSION] "; end
        _orig_fish_prompt
    end
    

ZMX 证明:专注单责,轻量即高效。结合现代终端(如 Ghostty)和 WM(如 Sway),构建零摩擦工作流。未来待二进制分发与配置。

资料来源: [1] https://github.com/neurosnap/zmx “zmx 提供终端 shell 会话持久化,支持 attach/detach 和状态恢复。” [2] https://bower.sh/you-might-not-need-tmux (作者博客,ZMX 灵感来源)。

(正文 1250 字)

查看归档