用 tmux 解决 Happy/Codex 关窗后掉线的问题

如果你在本地用 happy codex,经常遇到这样的问题:

  • 终端里启动一切正常
  • 手机端或 Web 端也显示在线
  • 但一旦关闭终端窗口,Happy 就不再回复消息

那么问题通常不在模型配置,而在于:Happy/Codex 会话仍然绑定在当前终端生命周期上
终端一关,前台会话或相关守护进程就可能收到退出信号,导致远端看起来“在线”,实际上本地执行端已经断了。

这篇文章给出一套更稳的方案:使用 tmux 托管 Happy/Codex 会话,让它在你关闭 iTerm2 窗口后仍然继续运行。


问题本质

很多人第一反应是:

happy daemon start
happy codex

然后关闭终端窗口,期待 Happy 继续在后台工作。

但现实里,这种方式并不总是可靠。原因很简单:

  • happy codex 是一个交互型 CLI
  • 它往往仍然依赖当前终端会话
  • 关闭窗口时,进程可能收到 SIGHUPSIGTERM 或类似退出信号
  • 最终表现就是:前端显示在线,但消息已经没人处理

也就是说,不是 Happy 配错了,而是会话没有真正脱离终端


为什么选 tmux

tmux 是一个终端复用器,它能把命令运行在一个独立的 session 里。
你的 iTerm2 窗口只是连接到这个 session 的“显示器”,不是进程本身。

这意味着:

  • 你可以关闭 iTerm2 窗口
  • tmux session 还在
  • happy codex 也还在
  • 之后可以重新连回去继续查看

对于 happy codex 这种交互型程序,这是比裸跑、比普通后台命令都更靠谱的方案。


使用环境

本文场景基于:

  • macOS
  • iTerm2
  • happy
  • codex
  • tmux

第一步:安装 tmux

先安装 tmux

brew install tmux

安装完成后,检查版本:

tmux -V

如果输出类似下面这样,就说明安装成功:

tmux 3.5a

第二步:用 iTerm2 进入 tmux 控制模式

在 iTerm2 里执行:

tmux -CC new -s happy

这里的 -CC 表示使用 iTerm2 的 tmux 集成控制模式。
执行后,iTerm2 会弹出一个新的 tmux 窗口,并显示类似提示:

** tmux mode started **
esc    Detach cleanly.
X      Force-quit tmux mode.

这说明你已经进入了正确的 tmux 会话。


第三步:在 tmux 会话里启动 Happy

在这个新弹出的 tmux 窗口里执行:

happy daemon start
happy codex

建议按顺序执行,不要省略。

作用分别是:

  • happy daemon start:启动 Happy 的后台守护
  • happy codex:启动 Codex 会话

到这里,Happy/Codex 就是在 tmux session 里运行了,而不是直接依附于普通终端窗口。


第四步:确认会话可用

启动完成后,先确认两件事:

  1. Happy 客户端里能正常收到回复
  2. 本地状态正常

你可以新开一个普通终端窗口检查:

happy daemon status
happy daemon list

如果 daemon 正常、session 也存在,就说明当前状态基本可用。


第五步:正确“退出”,而不是直接关窗口

这是最关键的一步。

如果你想让 Happy/Codex 留在后台继续运行,不要直接粗暴关闭会话
正确做法是在 tmux 控制窗口中按:

esc

这一步的作用是:

  • cleanly detach
  • 断开 iTerm2 与 tmux session 的连接
  • 但 tmux session 本身继续留在后台运行

detach 完成后,你再关闭 iTerm2 窗口。

一句话总结:

  • esc
  • 再关窗口

不要反过来。


以后怎么重新连回去

如果你之后想重新查看这个 Happy/Codex 会话,执行:

tmux -CC attach -t happy

这会重新连接到名为 happy 的 tmux session。

如果你不确定 session 名字,可以先看列表:

tmux ls

如何停止 Happy 和 tmux

如果你想彻底停止整个后台会话,建议按这个顺序:

先重新连接:

tmux -CC attach -t happy

然后在会话中执行清理:

happy doctor clean

如果确认 Happy 已经停掉,再退出 tmux shell:

exit

如果还需要直接杀掉 tmux session,也可以执行:

tmux kill-session -t happy

常见误区

误区一:只要 happy daemon start 了,就一定能关终端

不是。

happy daemon start 只表示 daemon 启动了,不代表你后面启动的 happy codex 会话已经完全脱离当前终端。


误区二:关闭 iTerm2 窗口等于后台运行

不是。

普通终端窗口关闭时,很多 CLI 程序都会收到退出信号。
如果没有 tmux 这类托管层,Happy/Codex 很可能会一起断掉。


误区三:是 Codex 配置有问题

大多数时候不是。

如果你本地确实已经配置为 Codex,但关闭窗口后仍然不回复,通常说明问题出在会话托管方式,不是模型本身。


内存占用会不会很严重

一般来说:

  • tmux 本身内存占用非常小
  • 真正占内存的是 happycodex、MCP bridge 和相关子进程

也就是说,tmux 不是主要负担
如果你担心资源占用,重点应该观察的是 happy codex 相关进程,而不是 tmux

长期后台运行时,建议:

  • 定期观察内存占用
  • 如果会话挂得太久、明显变卡,可以重启一次
  • 必要时执行:
happy doctor clean

最短操作流程

如果你只想记住最核心的步骤,看这一段就够了:

安装:

brew install tmux

启动:

tmux -CC new -s happy
happy daemon start
happy codex

后台保活:

  • 在 tmux 窗口里按 esc
  • 然后再关闭 iTerm2 窗口

重新连接:

tmux -CC attach -t happy

停止:

happy doctor clean
tmux kill-session -t happy

结论

happy codex 关闭终端后不稳定,问题核心通常不是 Happy 本身“不能用”,而是它仍然绑定在当前终端生命周期上。

最简单、最稳妥的解决方案,就是:

tmux 托管 happy codex,再通过 iTerm2 的 tmux 集成来连接和断开。

这样做的好处是:

  • 不依赖当前终端窗口
  • 关掉 iTerm2 后会话仍然在
  • 需要时可以重新 attach 回来
  • 比直接裸跑 happy codex 更稳定
Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐