Codex CLI 的后台守护进程:每小时连一次 chatgpt.com、停不干净;Claude Code 这边又留了什么
关掉终端后,两款 CLI 都可能留下进程。区别在于:这些进程因何启动,又能自行做什么。Codex 的自动启动开关默认开启。符合条件的环境中,未使用 --no-daemon 就会随交互式会话启动守护进程。它的日志每小时记录一次更新流程,我们这台机器上的后端也确实被一次定时检查换掉了。Claude Code 的后台会话管理进程则在会话转入后台时按需启动,日志大约每八小时记录一次登录 token 检查,并在安装器替换二进制文件后自行重启。Codex 文档列出了 --no-daemon 和功能开关命令,但我们查过的四份参考文档都没写出开关名称;Claude Code 则有专门介绍后台会话管理进程和更新器的页面。两家都能关闭。
30 秒看懂结论
10 月 12 日,有人把一条 GitHub 问题报告 发到了 Hacker News,标题是“Codex CLI installs a persistent, self-updating background daemon by default”。太平洋时间 10 月 15 日 10:22,我们查看时,这条帖子已有 606 分、292 条评论。原 问题报告 提交于 9 月 25 日,作者用的是 0.157.0。他描述的变化是:现在只要打开 Codex 会话,就会启动后台服务进程,把整个 Codex 包复制到 ~/.codex,再启动一个每小时检查更新、能够重启后端的更新器。关掉终端后,这套后台守护进程(daemon)仍会继续运行。
我们在同一台 Mac 上同时使用 Codex 和 Claude Code,于是用同一把尺子查了一遍各自留下的进程。下面的实测来自进程列表、日志、一次每小时检查的现场观察,以及隔离 HOME 目录的实验;我们没有把 问题报告 中的说法直接当成自己的测量结果,也不是替哪一家说话。
- 我们自己的 Codex 守护进程早就在跑,日志与 问题报告 描述相符。更新器于 10 月 14 日 14:37 启动。14:42,日志记录了成功的
installer_fetch和installer_run,选中 0.162.1 发布版;它启动时用的还是 0.161.0 的副本。随后,它以 60 秒宽限期请求重启后端,并在同一秒内启动了新后端。五分钟后,日志又记录了同样的获取与运行阶段,此后每小时 47 分一次,到次日 09:47 又记录了 19 次。 - 我们盯住了 10:47 那次检查。10:47:34 和 10:47:35,更新器进程打开了到两个地址 443 端口的 TCP 连接,其中一个地址是我们机器上
chatgpt.com当时解析出的地址。日志记录的installer_fetch耗时 345 ms,installer_run耗时 209 ms。二进制里嵌着命令curl -fsSL https://chatgpt.com/codex/install.sh | CODEX_NON_INTERACTIVE=1 sh,可以据此推测这些阶段的用途。但我们没有抓取请求内容,也没有追踪运行阶段具体执行了什么。约每 0.8 秒一次的进程轮询中,更新器下面除后端外,没有采样到其他进程。 - 关终端停不掉,
stop也停不全。在全新的 HOME 目录里打开终端界面(TUI),服务进程和更新器都会启动,同时复制一份 323 MiB 的包。退出 TUI 后,两者的父进程都变成 PID 1,继续运行。codex app-server daemon stop只结束了服务进程,至少 80 秒后更新器仍然存活。禁用daemon_auto_start,或以codex --no-daemon启动后,两者都不会出现,也不会复制包。 - Claude Code 的后台组件,启动条件和职责都不同。后台会话管理进程(supervisor)
claude daemon run已运行 19.7 小时,状态记录显示它由一个claude进程按需启动。它的日志约每八小时记录一次登录 token 检查,还记录了两次安装器替换二进制文件后的自行重启。另有一个后台会话已被列为完成、空闲,状态文件最后更新时间是前一晚 19:50:57,进程到第二天早上却还活着:常驻内存约 330 MiB,有三条连向api.anthropic.com443 端口的 TCP 连接。为什么没有退出,我们没查清。 - 两家都留着旧版本。Codex 的发布副本占 644 MiB,旁边还有 323 MiB 的 npm 安装;Claude Code 留了四个版本,共 903 MiB。
结论:如果你希望后端随终端启动和退出,只运行自己安装的那个二进制,Codex 需要一个功能开关、一条停止命令,再手动终止更新器。--no-daemon 有文档,但我们查过的四份参考文档都没写出那个开关的名称。Claude Code 的 supervisor 和更新器有专门文档,也列出了关闭开关;我们发现的那处异常,则说明值得偶尔运行一次 claude daemon status。在我们检查的安装方式下,两款工具都默认在后台更新,都不会先问用户。
Codex 的守护进程 怎么来的
Codex 的 VS Code 扩展、桌面应用和 Remote Control 等客户端,都通过 JSON-RPC 与 app-server 进程通信。到了九月,OpenAI 让终端客户端也改用共享的 app-server,并将它作为受管理的守护进程运行。从已合并的 合并请求 可以看出这项改动是怎样推进的:
| 日期 | 改动 |
|---|---|
| 9 月 17 日 | 合并“Add opt-in automatic background server startup”(#46117)和“Record daemon startup and update telemetry with consent handling”(#46126):加入需要用户主动开启的后台服务自动启动功能,以及处理用户同意设置的启动和更新遥测记录 |
| 9 月 22 日 | 合并“Enable automatic daemon startup by default”(#47179):改为默认自动启动 |
| 9 月 25 日 | 针对 0.157.0 提交 问题报告 #48195,要求 daemon_auto_start 改为由用户主动开启 |
| 10 月 3 日至 10 月 4 日 | 合并“Skip daemon auto-start for Windows-mounted WSL homes”(#50555)和“Use the managed daemon for eligible remote-control launches”(#50803);两项改动均列入 10 月 8 日的 0.162.0 发布说明 |
| 10 月 11 日 | 合并“Allow restarting managed background servers from the TUI”(#53173):允许从 TUI 重启受管理的后台服务 |
| 10 月 12 日 | 问题报告 #48195 被发到 Hacker News |
| 10 月 13 日 | 又出现两条 问题报告:守护进程跨会话泄露环境变量(#53547);Windows 上每小时运行的 install.ps1 被 McAfee 当作无文件恶意软件拦截(#53778) |
问题报告 作者列出了四种行为:所有 Codex 窗口关掉后,守护进程仍不退出;~/.codex/packages 下多出一份 374 MB 的包;更新器在启动五分钟后首次检查,之后每小时检查,并会重启后端;守护进程沿用最初启动它的那个会话的环境变量。10 月 15 日查看时,这条 问题报告 仍开着,有 198 个表情回应,没有维护者回复。我们也没找到已经合并、将其改为默认关闭的改动。
Hacker News 的第一条评论支持自动更新,理由是变化太快,浏览器也这么做(原文:“this stuff is moving fast, should update automatically… Browsers do it”)。另一位评论者 timdorr 则说,Claude Code 的运行方式也一样(原文:“the same operational model”)。这两种说法,都需要对照机器上实际运行的东西来看。
过去 20 小时,日志里发生了什么
我们使用的是通过 npm 安装的 Codex CLI 0.162.1。为写这篇文章,我们没有调整任何设置;开始检查时,守护进程已经在运行。
先看进程关系。一共两个进程,运行的都是 ~/.codex/packages/app-server-daemon/releases/0.162.1-aarch64-apple-darwin/bin/codex,没有使用 npm 安装目录里的二进制。更新器的父进程是 PID 1,服务进程的父进程则是更新器:
PID 56600 parent 1 started 14 Oct 14:37 codex app-server daemon pid-update-loop
PID 58526 parent 56600 started 14 Oct 14:42 codex app-server --listen unix:// --analytics-default-enabled --managed-daemon
更新器监听 ~/.codex/app-server-daemon/daemon-updater.sock;服务进程监听 /private/tmp/codex-daemon-501/ 下的 socket,~/.codex/app-server-control/ 中有指向它的符号链接。第一次截取进程状态时,没有打开的 TCP 连接。服务进程自己的日志中,当天早上只有一条记录:09:38:47 的 failed to refresh available models: request timed out。这表明它尝试联网但失败了,我们没有捕获到实际通信内容。
再看更新器日志。~/.codex/app-server-daemon/daemon-updater.stderr.log 是逐条记录事件的 JSON 日志。从进程启动到我们读取前的最后一条记录,共覆盖 19 小时 10 分钟:
| 时间(10 月 14 日,太平洋时间) | 事件 | 详情 |
|---|---|---|
| 14:37:10 | 更新器进程启动 | PID 56600 |
| 14:42:10 | installer_fetch 成功 | 276 ms |
| 14:42:15 | installer_run 成功 | 4,537 ms |
| 14:42:15 | package_selected | 发布版 0.162.1,触发原因 scheduled |
| 14:42:15 | restart_requested | shutdownGraceSeconds: 60 |
| 14:42:15 | shutdown_requested、shutdown 成功 | 旧后端 PID 56584,52 ms |
| 14:42:15 | process_spawned、readiness 成功 | 新后端 PID 58526 |
| 14:47:16 | installer_fetch、installer_run、package_selected | 465 ms、188 ms,再次选中 0.162.1 |
| 15:47 至次日 09:47 | 每小时 47 分记录上述三个事件 | 19 次 |
也就是说,更新器最初从 0.161.0 的副本运行,启动五分钟零五秒后,就安装了 0.162.1,并换掉后端。配置的宽限期是 60 秒,日志记录的关闭阶段实际耗时 52 ms。那一刻是否有请求正在处理,日志没有写。问题报告 链接了另一份报告,称这种重启会打断正在进行的对话;我们没有观察到对话被打断。
这次更新之后,五分钟后又跑了一次,接下来每小时一次。更新后的 20 次记录中,installer_fetch 通常耗时 190 至 465 ms,例外是 06:47 的 1,399 ms 和 19:47 的 4,008 ms;installer_run 通常耗时 168 至 371 ms,例外是 19:47 的 1,312 ms。
每小时的检查,究竟做了什么?这里需要把三类证据分开。
日志能确认的是:每次都有先获取、再运行两个阶段,都报告成功;之后是 package_selected,触发原因标为 scheduled。
现场观察能确认的是:10 月 15 日 10:47 那次检查中,我们用 lsof 和约每 0.8 秒一次的进程轮询,看到更新器进程自己打开了连接。10:47:34,它连向 172.64.155.209 的 443 端口,这是本机当时解析 chatgpt.com 得到的地址之一;10:47:35,又出现了到 104.18.43.139 的连接,这个地址我们没能确认归属。日志记录 installer_fetch 耗时 345 ms,installer_run 耗时 209 ms。进程轮询没有采样到更新器下面除后端外的其他进程,但只运行 209 ms 的命令解释器进程完全可能落在两次采样之间。
二进制提供的线索是:用 strings 可以找到 curl -fsSL https://chatgpt.com/codex/install.sh | CODEX_NON_INTERACTIVE=1 sh,以及 Windows 使用的 irm https://chatgpt.com/codex/install.ps1 | iex。10 月 13 日提交的 Windows 问题报告 也描述了更新器每小时把 install.ps1 通过管道交给 PowerShell 执行。
我们实际看到的是更新器自己打开的 TLS 连接和日志阶段名,没有抓请求内容,也不知道运行阶段具体执行了什么。安装脚本命令是二进制字符串和 Windows 问题报告 指向的解释,不是我们亲眼观察到的执行过程。
磁盘上留下了什么?du 报告 ~/.codex/packages 占 644 MiB:守护进程首次启动时复制的 0.161.0 占 321 MiB,五分钟后安装的 0.162.1 占 323 MiB。作为复制来源的 npm 安装另占 323 MiB。过了一天,那份旧副本还在。
生命周期实测:启动、退出和停止
为了查清哪些进程会启动、哪些会留下,以及 stop 到底能停掉谁,我们为 Codex 准备了一个空的 HOME 目录,里面只有 auth.json 和一行内容的 config.toml。这样不会碰到原本就在运行的守护进程。随后在 tmux 中打开 TUI,不发送提示词,只观察进程列表。
| 操作与时间 | 测试 HOME 目录下的进程情况 |
|---|---|
| 打开 TUI 后 25 秒 | 出现 app-server --managed-daemon 和 daemon pid-update-loop,父进程都是 TUI 的启动进程;packages/ 中复制了 323 MiB;两个 PID 文件均已写入 |
| 连按两次 Ctrl-C 退出 TUI,8 秒后 | 两个进程仍在运行,父进程都变成 PID 1 |
运行 codex app-server daemon stop,10 秒后 | 服务进程已退出,更新器仍在运行 |
运行 stop 至少 80 秒后 | 更新器仍在运行,最后由我们手动终止 |
这复现了 问题报告 作者在尝试关闭功能时发现的问题。命令明明输出了 "status": "stopped",更新器却还活着。服务进程停掉以后,它是否还会按小时继续检查,我们没有测。
我们又换了两个全新的 HOME 目录,分别测试:
- 先运行
codex features disable daemon_auto_start,它会在config.toml的[features]下写入daemon_auto_start = false。之后打开 TUI,没有服务进程,没有更新器,也没有创建packages/目录。 - 保留开关默认值,但改用
codex --no-daemon启动 TUI。结果相同:没有后台进程,也没有复制包。
如果要把这个实验写成脚本,还有一个容易踩到的问题:第一次尝试时,我们的 HOME 路径太长,更新器因 Error: path must be shorter than SUN_LEN 启动失败。这是 Unix socket 的路径长度限制。那次只有服务进程启动,关闭 TUI 后,也只有 app-server 留了下来。
怎样彻底关掉?codex features list 会列出这个开关:
daemon_auto_start stable true
codex features 命令有文档。CLI 参考文档也列出了 --no-daemon,意思是运行交互式 CLI 时不使用共享后台服务(原文:“Run the interactive CLI without the shared background server”),并说明它不能与 --remote 或 codex agents 同用。然而,开关名称 daemon_auto_start 没有出现在 CLI 参考文档、开发者命令页或配置参考文档中,用户只能从 问题报告 或 features list 里找到它。
要停止已经运行的守护进程,并阻止以后自动启动,可以依次运行:
codex features disable daemon_auto_start # future sessions start no daemon (tested)
codex app-server daemon stop # stops the server, not the updater (tested)
updater_pid=$(python3 -c 'import json,os;print(json.load(open(os.path.expanduser("~/.codex/app-server-daemon/daemon-updater.pid")))["pid"])')
ps -o user=,pid=,lstart=,command= -p "$updater_pid" # inspect before acting
先检查 ps 的输出:用户应当是你自己,命令应以 app-server daemon pid-update-loop 结尾。确认无误后,再运行 kill "$updater_pid",并检查进程是否已退出。如果显示的是别的进程,或没有任何输出,先停下来查清楚。
至于 ~/.codex/packages/app-server-daemon 下的发布副本,要不要删除可以另行决定;先确认没有进程还在使用它们。0.162.0 发布说明提到,符合条件的 Remote Control 启动会使用受管理的守护进程。如果你依赖 Remote Control,应先读相关文档;这部分我们没有测试。
Claude Code 留下了哪些进程
同一台 Mac 上还装着 Claude Code 2.1.300,使用的是原生安装器。我们用相同工具检查了它留下的进程。
先看托管后台会话的 supervisor。claude daemon run --origin transient 已运行 70,814 秒,也就是 19.7 小时。claude daemon status 记录的启动来源,是我们某个项目目录中的 claude 进程,PID 40368,启动方式为按需启动。
claude daemon --help 的说明是:当前版本不支持安装为系统服务,守护进程按需运行,最后一个客户端断开后就会退出。原文:“Service install is disabled in this version — the daemon runs on demand and exits when the last client disconnects.” 这是帮助文本的说法。启动它的那个进程当时还在,我们没有断开全部客户端,也就没有验证最后一个客户端断开后的行为。
文档列出的职责包括:托管通过 /bg 或 agent view(代理视图)转入后台的会话,让它们在没有终端时继续工作;会话完成、没有客户端连着约一小时后,回收它的进程;会话意外退出时,将其重启。自动更新后,supervisor 会切换到新版本自行重启,并在后台迁移空闲会话(原文:“restarts itself onto the new version and moves idle sessions over in the background”)。文档还说,正在工作、等待用户输入或有客户端连着的会话不会被打断。
日志能证实哪些行为?安装器替换二进制文件后,supervisor 自行重启过两次:10 月 7 日 22:28,从 2.1.293 升到 2.1.294;10 月 14 日 14:36,从 2.1.294 升到 2.1.300。两次日志都先记下 ~/.local/bin/claude 的二进制文件已变化、将自行重启,随后记录新的 supervisor 进程成功抢到锁。
此外,日志约每八小时记录一次登录 token 检查,内容为“auth: proactive refresh starting … scheduling proactive refresh in 28514s”,即开始主动刷新登录 token,并安排下次刷新。重启有没有影响正在工作的会话,日志无法判断;不中断会话是文档给出的保证。supervisor 还会保留一个预热的备用工作进程,供下一个后台会话使用。
有个已完成的会话,进程却还活着。claude agents --json --all 列出了一个仍使用 Claude Code 2.1.293 的后台会话。它的工作进程从 10 月 7 日 17:23 开始运行,会话列表记录的派发来源是我们自己的代理调度工具。
10 月 15 日早上检查时,状态文件写着 done,最后更新时间为 10 月 14 日 19:50:57。然而进程仍然存活,常驻内存约 330 MiB,有三条到 api.anthropic.com 443 端口的 TCP 连接,距启动已接近八天。它没有被钉住(Ctrl+T)。supervisor 的状态输出提示它来自另一个 CLI 版本,并解释大多数此类会话仍能连接、空闲后会自动升级,但执行命令的会话不会重新启动。原文:“from a different CLI version (most stay attachable and upgrade automatically once idle — exec runs never respawn)”。
按文档描述,它似乎应当被那条一小时回收规则覆盖。但我们没能确定它究竟何时完成,也不知道规则的全部条件是否都满足,更没有查清进程为何仍在运行。我们只观察到了这个现象,没有复现。把它写出来,是因为这种情况只有查进程列表才会发现,单读文档看不到。
更新由谁完成?文档说,CLI 会在启动时、以及运行期间定期检查更新(原文:“checks for updates on startup and periodically while running”),在后台下载并安装,新版本在下次启动 Claude Code 时生效(原文:“take effect the next time you start Claude Code”)。文档将这项工作归于正在运行的 CLI,没有将它描述为独立进程;我们从日志中看到的,则是 supervisor 在二进制文件被替换后自行重启。
claude doctor 会报告更新渠道和最近一次尝试。我们使用 latest,而 10 月 15 日的 stable 仍指向 2.1.292。版本目录里有四个二进制文件:2.1.283、2.1.293、2.1.294、2.1.300,共 903 MiB。文档只承诺在使用自定义启动器时保留每个版本;我们使用的却是安装脚本自己建立的符号链接。
关闭办法都有文档。DISABLE_AUTOUPDATER=1 会关闭后台更新,保留手动 claude update;DISABLE_UPDATES=1 则连手动更新也禁用。Homebrew 和 WinGet 安装默认不自动更新,设置 CLAUDE_CODE_PACKAGE_MANAGER_AUTO_UPDATE=1 才会开启。
claude daemon stop --any 会停止 supervisor 及其托管的会话;加上 --keep-workers,可以让会话进程继续运行,等待新的 supervisor 接管。在 macOS 和 Linux 上,新的 supervisor 必须在约一分钟内启动,可以运行 claude agents;否则会话就会停止。claude daemon status 可查看 supervisor 是否运行及其版本。将 disableAgentView 设为 true,或设置 CLAUDE_CODE_DISABLE_AGENT_VIEW,可以彻底关闭后台代理。以上都有文档可查。
两家放在一起看
| Codex CLI 0.162.1(npm,macOS) | Claude Code 2.1.300(原生安装,macOS) | |
|---|---|---|
| 哪些进程可能比终端活得更久 | app-server 和更新器 | 后台会话管理进程、预热的备用工作进程,以及它托管的会话进程 |
| 何时启动 | daemon_auto_start 为默认值时,打开交互式会话就启动;从 0.162.0 起,HOME 目录位于 Windows 挂载盘的 WSL 环境除外 | 会话转入后台、打开 agent view,或客户端派发后台会话时 |
| 会不会自行退出 | 实测没有:退出 TUI 后仍在运行,直到执行 stop,再手动终止更新器 | 帮助文本说最后一个客户端断开就退出,未实测;我们的进程已运行 19.7 小时,状态记录的启动者是 PID 40368 |
| 如何自行更新 | 日志记录启动五分钟后的获取与运行周期,约五分钟后再一次,此后每小时一次;其中一次安装了新版本,以 60 秒宽限期请求重启后端 | 运行中的 CLI 在后台下载新版本,下次启动生效;之后 supervisor 自行重启,日志中观察到两次。会话不中断是文档说法 |
| 实际运行哪个二进制 | ~/.codex/packages 下的独立副本,与 npm 安装的版本分开 | 新启动的进程通过安装器建立的符号链接选择版本;已有进程可能留在旧版,我们的后台会话仍是 2.1.293 |
| 自行联网做什么 | 观察的那次检查打开了到 443 端口的 TCP 连接,其中有一个 chatgpt.com 地址;服务进程日志还记录了一次失败的模型列表刷新 | 约每 8 小时检查登录 token,来自日志;更新器检查版本,来自文档 |
| 旧版本占用 | 2 份发布副本共 644 MiB,另有 323 MiB 的 npm 安装 | 4 个版本,共 903 MiB |
| 文档写到了什么 | CLI 参考文档有 --no-daemon 和 codex features,但它、开发者命令页和配置参考文档都没写出 daemon_auto_start 的名称 | supervisor、更新器、各项开关和状态文件都有文档 |
| 如何关闭 | codex features disable daemon_auto_start 或 --no-daemon,均已实测;已经运行的还需 daemon stop,再终止更新器 | DISABLE_AUTOUPDATER=1 / DISABLE_UPDATES=1;claude daemon stop --any;disableAgentView |
你可以怎么做
- 先查自己机器上的情况。
ps -axo pid,ppid,etime,command | grep -E 'codex app-server|claude daemon|claude bg-'可以列出相关进程和运行时长。codex app-server daemon version与claude daemon status可以查看版本。花十秒钟,就能知道自己机器上实际跑着什么。 - 如果希望 Codex 随终端启动和退出,先禁用自动启动开关,停止已有守护进程,再按 PID 终止更新器,最后用
codex features list和进程列表核对。Remote Control 使用受管理守护进程的方式可能受影响;我们没有测试。 - 如果决定保留 Codex 守护进程,就需要接受这些行为:日志每小时记录一次更新流程;我们观察的那次连到了
chatgpt.com解析出的地址;更新流程可以用 60 秒宽限期请求重启后端。此外,问题报告 作者报告守护进程会沿用第一个会话的环境变量,相关报告 #53547 仍未关闭。 - 给 Claude Code 明确选好更新方式。如果要固定版本,可以设置
DISABLE_AUTOUPDATER=1。如果保留自动更新,要知道stable会比latest落后几个版本。用claude doctor确认自己当前的渠道。 - 偶尔查一次
claude daemon status。如果它提示有工作进程来自其他 CLI 版本,可以先运行claude daemon stop --any --keep-workers,再在约一分钟内运行claude agents,启动新的 supervisor 并重新连接这些进程。文档说,会话只会等待新的 supervisor 约一分钟,之后就会停止。操作完成后,分别核对 supervisor 和工作进程的版本;已经完成且不再需要的会话,可以用claude rm <id>移除。 - 需要空间时再清理旧版本。
~/.codex/packages/app-server-daemon/releases和~/.local/share/claude/versions都是普通目录。保留current符号链接或启动器指向的版本,也要保留仍有进程正在使用的版本。
本次实测的边界
只看了一台 Mac、一天。机器上装了两款工具。我们读取了 19 小时的 Codex 更新器日志,现场观察了一次每小时检查;Claude Code 的 supervisor 当时已运行 19.7 小时。Linux 和 Windows 的行为来自 问题报告,不是我们的实测。
每小时的运行阶段执行了什么,尚不能确认。我们看到了一次检查中的 TCP 连接和日志阶段名,也在二进制中找到了安装命令;但没有抓取请求内容,没有追踪运行阶段。
没有观察到更新打断对话。日志中那次更新发生在我们开始观察之前。问题报告 链接的另一份报告提到对话被打断,我们没有复现;前文的宽限期只是日志里的配置值。
stop 之后是否继续按小时检查,没测到。服务进程停止至少 80 秒后,更新器仍存活;我们没有等满一小时,就手动终止了它。
只测了 npm 安装的 Codex CLI。Homebrew 安装、桌面应用、VS Code 扩展和 Remote Control 可能采用不同方式启动 app-server,这次没有覆盖。
已完成的 Claude Code 会话为何仍存活,原因不明。我们也没验证 supervisor 是否真会在最后一个客户端断开后退出:没有断开全部客户端,没有做相应退出测试。状态记录的启动进程为 PID 40368,当时它还在运行。
Claude Code 更新时是否始终不中断会话,日志不能证明。日志能看出 supervisor 自行重启;对正在工作会话的保证来自文档。
相关阅读
- AI 编程代理会在磁盘上写什么——各款工具留下的文件、缓存和会话记录。
- Claude Code 的磁盘占用与清理方法——空间花在哪里,哪些内容可以安全删除。
- Claude Code 的模组可以绕过拒绝规则——另一个实测案例:机器上实际执行的操作,比设置看起来允许的更多。
- Codex 与 Claude Code 的用量限制——两款工具怎样计量收费的用量。
来源
- OpenAI——CLI: make
daemon_auto_startopt-in — a persistent, self-updating background daemon shouldn’t be the default,问题报告 #48195,2026 年 9 月 25 日提交;2026 年 10 月 15 日查看时仍未关闭,有 198 个表情回应、19 条评论。 - Hacker News——Codex CLI installs a persistent, self-updating background daemon by default,2026 年 10 月 12 日发布;太平洋时间 10 月 15 日 10:22 查看时有 606 分、292 条评论。
- OpenAI——Add opt-in automatic background server startup,合并请求 #46117,2026 年 9 月 17 日合并;Enable automatic daemon startup by default,合并请求 #47179,2026 年 9 月 22 日合并。
- OpenAI——Codex 0.162.0 发布说明,2026 年 10 月 8 日,包含“Skip daemon auto-start for Windows-mounted WSL homes”和“Use the managed daemon for eligible remote-control launches”两项改动。
- OpenAI——Daemon server leaks environment variables across sessions,问题报告 #53547;Windows: managed daemon updater pipes install.ps1 into powershell.exe every hour,问题报告 #53778。两条均于 2026 年 10 月 13 日提交。
- OpenAI——命令行选项,其中的
--no-daemon和codex features条目;开发者命令;Codex App Server;配置参考文档。2026 年 10 月 15 日查阅,四份文档都没有写出daemon_auto_start的名称。 - Anthropic——Claude Code:通过 agent view 管理多个代理,后台会话管理进程、状态存储位置、关闭 agent view 的相关章节,以及必须在一分钟内启动新 supervisor 的说明。
- Anthropic——Claude Code:安装与设置,自动更新部分。
- Anthropic——Claude Code:CLI 参考文档,
claude daemon及后台会话命令。 - Anthropic——Claude Code:环境变量,
DISABLE_AUTOUPDATER、DISABLE_UPDATES、CLAUDE_CODE_PACKAGE_MANAGER_AUTO_UPDATE。
我们的测量均于太平洋时间 2026 年 10 月 15 日,在同一台 macOS 机器上完成。使用 ps 和 lsof 查看进程;读取 Codex 守护进程的 daemon-updater.stderr.log(10 月 14 日 14:37 至 10 月 15 日 09:47)和 daemon.stderr.log;在 10:46:40 至 10:49:10 之间,以约每 0.8 秒一次的频率轮询进程,同时用 lsof -i 观察每小时检查时的连接;对守护进程二进制运行 strings;查看 codex features list;用 npm 安装的 Codex CLI 0.162.1 做三次隔离 HOME 目录实验,分别保留默认开关、禁用开关、使用 --no-daemon。Claude Code 部分使用了 claude daemon status、claude agents --json --all、~/.claude/daemon.log 和 claude doctor;目录大小来自 du -sh。Claude Code 为原生安装的 2.1.300。
FAQ
Codex CLI 的后台守护进程到底做了什么?在符合条件的环境中,daemon_auto_start 保持默认值、且启动时未加 --no-daemon,就会随 Codex 交互式会话启动共享的 app-server 进程和独立的更新器。关掉终端后,两者仍会运行。我们在 Mac 上使用的是 npm 安装的 Codex CLI 0.162.1。更新器启动五分钟后,日志记录了成功的 installer_fetch 和 installer_run 阶段,随后选中 0.162.1,替换最初复制的 0.161.0,并以 60 秒宽限期请求重启后端。约五分钟后,日志又记录了相同阶段,之后每小时一次。在我们盯住的那次检查中,更新器进程打开了到 443 端口的 TCP 连接,其中一个地址是 chatgpt.com 当时解析出的地址;我们没有追踪运行阶段具体执行了什么。守护进程使用 ~/.codex/packages 下独立的 323 MiB Codex 包副本,与 npm 安装分开。
怎样关闭 Codex 的守护进程?我们在隔离的 HOME 目录里验证了两种方法。codex features disable daemon_auto_start 会把开关写入 ~/.codex/config.toml,此后打开 TUI 不会启动守护进程,也不会复制包。codex --no-daemon 对单次启动有同样效果,CLI 参考文档也列出了它。对于已经运行的守护进程,实测 codex app-server daemon stop 只结束了服务进程,更新器仍然存活。因此还要从 ~/.codex/app-server-daemon/daemon-updater.pid 读取 PID,核对命令行,再手动终止该进程。确认没有进程使用后,可以删除 ~/.codex/packages/app-server-daemon 下的发布副本。codex features list 能列出 daemon_auto_start,但 CLI 参考文档、开发者命令页和配置参考文档都没有写出这个名称。
关掉 Claude Code 后,也会留下进程吗?会有这种情况。会话转入后台、打开 agent view,或客户端派发后台会话时,后台会话管理进程 claude daemon run 会按需启动,托管这些会话,让它们在没有终端的情况下继续工作。帮助文本说,最后一个客户端断开后它就会退出;这一点我们没有实测。我们 Mac 上的这个进程已运行 19.7 小时,状态记录显示它由一个 claude 进程按需启动,旁边还有一个预热的备用工作进程和一个后台会话的进程。更新机制要另看:文档说,下载和安装新版本由运行中的 CLI 在后台完成,下次启动时生效;supervisor 的日志则显示,安装器替换二进制文件后,它自行重启了。
怎样关闭 Claude Code 的后台更新和 supervisor?设置 DISABLE_AUTOUPDATER=1 可以关闭后台更新,保留手动 claude update;DISABLE_UPDATES=1 则连手动更新也禁用。Homebrew 和 WinGet 安装默认不自动更新。claude daemon stop --any 会停止 supervisor 及其托管的后台会话;加上 --keep-workers 则保留会话进程,等待新的 supervisor 接管。在 macOS 和 Linux 上,必须在约一分钟内运行 claude agents 启动新的 supervisor,否则会话会停止。将 disableAgentView 设为 true,或设置 CLAUDE_CODE_DISABLE_AGENT_VIEW,可以彻底关闭后台代理。claude daemon status 可查看 supervisor 是否运行及其版本。
两款工具留下的版本副本各占多少磁盘?在我们的 Mac 上,du 报告 ~/.codex/packages 占 644 MiB,其中两份守护进程发布副本分别占 321 MiB 和 323 MiB;作为复制来源的 npm 安装还另占 323 MiB。Claude Code 的原生安装器在 ~/.local/share/claude/versions 下保留了四个版本,从 2.1.283 到 2.1.300,共 903 MiB。查看时,两款工具都没有自行清掉这些旧副本。
OpenAI 回应过把守护进程改为默认关闭的请求吗?在那条 问题报告 里没有。9 月 25 日提交的 问题报告 到 10 月 15 日仍未关闭,有 198 个表情回应、19 条评论,没有维护者回复。这个功能开关最初随 9 月 17 日合并的 合并请求 加入,需要用户主动开启;9 月 22 日合并的 合并请求 又把它改为默认开启。后来合并的改动包括:HOME 目录位于 Windows 挂载盘的 WSL 环境不再自动启动守护进程,以及增加重启命令。10 月 13 日又有两条 问题报告,分别报告守护进程跨会话泄露环境变量,以及 Windows 上每小时运行的安装脚本被杀毒软件拦截。
这篇对你有帮助吗?