12k
All articles

使用 caffeinate 让你的 Mac 在夜间 Agent 运行期间保持唤醒状态

在 Mac 上用 caffeinate 让 Claude Code、Codex 或构建任务整夜保持运行,用 pmset 验证 assertion,并了解合盖限制。

OpenReplay Team
OpenReplay Team
使用 caffeinate 让你的 Mac 在夜间 Agent 运行期间保持唤醒状态

caffeinate 是 macOS 内置的命令行工具,可在任务运行期间阻止 Mac 进入睡眠状态。其最实用的用法是 caffeinate -i <你的命令>——它会包裹一个进程,在进程运行期间保持系统唤醒,并在进程退出时自动释放。如果你曾经合上笔记本盖子或离开一段时间后,发现彻夜运行的 Claude Code、Codex 或长时间构建任务已经中断,这个内置工具无需安装即可解决问题。本文将介绍关键标志参数、可靠的夜间运行方案、如何验证断言是否真正生效,以及 caffeinate 无法突破的唯一硬性限制。

核心要点

  • caffeinate 随 macOS 附带(自 OS X 10.8 起),无需安装,无需管理员权限,通过创建 IOKit 电源管理断言来工作——这与 Xcode 等应用保持 Mac 唤醒所使用的机制相同。
  • 在笔记本上,使用 -i 阻止空闲睡眠;-s 仅在接通交流电时有效,在使用电池时会被静默忽略;-d 会不必要地保持显示器常亮。
  • 包裹命令的方式(caffeinate -i npm run build)会在进程退出时自动释放断言,因此无需担心忘记关闭。
  • 仅凭 caffeinate 无法在合盖状态下保持 MacBook 唤醒:合盖会触发翻盖睡眠,软件断言在使用电池时无法覆盖此行为。
  • tmux 中运行夜间 Agent,确保断言在 Terminal 窗口关闭或崩溃后仍能存活。

caffeinate 在 Mac 上是什么(10 秒速览)

caffeinate 是 macOS 官方支持的命令行工具,通过创建电源管理断言来改变睡眠行为。自 OS X 10.8(2012 年)起,它已内置于 /usr/bin/caffeinate,无需安装,也无需管理员权限。其底层通过 IOPMAssertionCreateWithName 调用 IOKit 的电源断言 API——这是一种向电源管理系统动态请求特定系统行为的机制,也是应用程序在活跃工作期间保持 Mac 唤醒所使用的官方路径。

对于长时间运行的任务而言,最关键的特性是包裹模式。如果指定了一个实用程序,caffeinate 会代表该程序创建断言,断言在程序执行期间持续有效;否则,caffeinate 直接创建断言,断言在 caffeinate 退出前持续有效。官方 man 手册页中的典型示例是 caffeinate -i makecaffeinate 派生一个进程,在其中执行 make,并在该进程运行期间持续持有阻止空闲睡眠的断言。

caffeinate 的关键标志参数

在笔记本上,最重要的标志是 caffeinate -i:它阻止系统空闲睡眠,同时允许显示器变暗,这正是后台 Agent 或构建任务所需的行为。完整的文档标志集比大多数教程所介绍的更为丰富:

标志阻止的行为说明
-i空闲睡眠开发者默认选项;显示器仍可关闭
-d显示器睡眠保持屏幕常亮——对无头任务而言浪费电量
-m磁盘空闲睡眠对 CPU/网络密集型 Agent 很少需要
-s系统睡眠仅限交流电供电时有效
-u声明用户活动单次触发;重置空闲计时器
-t NN 秒后自动退出
-w pid持有断言直到指定 PID 退出

有两个细节常被其他教程误解。其一,-s 断言仅在系统使用交流电时有效——在使用电池时会静默失效,因此对于未插电的笔记本来说,它并非正确的默认选项。其二,如果显示器已关闭,-u 会将其点亮并阻止空闲睡眠;若未通过 -t 指定超时时间,该断言默认在 5 秒后超时。包裹任务的方式比裸断言更安全,因为它不会比任务本身存活更长时间:caffeinate -i npm run build 在构建期间阻止睡眠,并在构建完成后立即释放断言。

夜间 Agent 运行方案

要让 Claude CodeCodex CLI 或 Aider 整夜稳定运行,需直接包裹 Agent 的启动命令,并在终端复用器中运行,使其不依赖 Terminal 窗口保持打开状态。由于断言存活于 caffeinate 进程内部,Terminal 关闭或崩溃时断言也会消失——tmux 可提供真正的持久性:

# 启动一个分离的 tmux 会话,在整个生命周期内持有断言
tmux new-session -d -s agent 'caffeinate -i claude'

如果 Agent 已在另一个窗格中运行,无需重启——使用 -w 将新断言绑定到其现有进程 ID:

# 查找 PID,然后持有断言直到该进程退出
pgrep -f claude
caffeinate -i -w <pid>

在离开长达 8 小时的运行任务之前,请先验证断言是否真正生效。在另一个窗格中运行:

pmset -g assertions

输出中出现 PreventUserIdleSystemSleep 条目,即可确认 macOS 不会在任务运行期间触发空闲睡眠;当包裹的命令退出后,该条目将消失。这一诊断步骤是”寄希望于”夜间运行受保护与”确认”其受保护之间的关键区别。

caffeinate 能在合盖状态下保持 MacBook 唤醒吗?

仅凭 caffeinate 无法在合盖状态下保持 MacBook 唤醒。合盖会触发翻盖睡眠,软件电源断言在使用电池时无法覆盖此行为——这是无法绕过的硬性限制,也是为什么合上笔记本并拔掉电源后任务会立即中断的原因。

合盖运行仅在以下两种官方支持的情况下有效。第一种是 Apple 的翻盖模式:Apple 支持通过连接外接显示器、键盘和鼠标在合盖状态下使用 MacBook,但该设置有严格要求——没有外接显示器时无法使用,且可能带来散热方面的权衡。Apple 推荐的配置需要连接外接显示器、电源适配器以及外接键盘和鼠标或触控板。第二种是在”系统设置 → 电池 → 选项”中开启”显示器关闭时阻止自动睡眠”——但此选项要求计算机连接电源,在使用电池时无法按预期工作。

如果你确实需要在使用电池且合盖的情况下运行 Agent(例如将笔记本放在包里),caffeinate 并非合适的工具。Amphetamine 正是为此场景而设计的:其文档说明,使用 Amphetamine 时,Mac 无需外接显示器、键盘、鼠标或电源适配器即可使用合盖模式,因为它使用了一个公开可访问的 API 来禁用 Apple 的相关限制

以下是完整的对比真值表:

场景caffeinate -i电池 > 选项Amphetamine
开盖、空闲、使用电池保持唤醒保持唤醒保持唤醒
合盖、使用电池进入睡眠进入睡眠保持唤醒
合盖、接交流电 + 外接显示器/键盘保持唤醒保持唤醒保持唤醒
Terminal 窗口关闭或崩溃断言消失不受影响不受影响
包裹的命令完成自动释放不受影响会话继续

停止运行及注意事项

在前台运行时按 Ctrl+C 停止 caffeinate,或在包裹的命令完成后让其自动退出——包裹模式的设计使其很难被意外遗留运行。以下几个失效场景值得关注。不带包裹实用程序且不带 -t 的裸 caffeinate 会一直运行,直到手动停止;长时间保持 Mac 唤醒会加剧电池损耗、升高组件温度并增加 SSD 写入次数,因此应将断言范围限定在具体任务上。由于断言绑定于进程,关闭或崩溃 Terminal 会立即释放断言——这正是将 Agent 包裹在 tmux 中而非直接输入 caffeinate 并期望窗口整夜保持打开的核心理由。

何时需要更多工具

caffeinate 适用于以下场景:Mac 已接通电源或处于开盖状态,且你希望对特定的夜间任务提供保护并在完成后自动清理。当你需要在使用电池且合盖的情况下运行时,请转而使用 Amphetamine 及其基于会话的控制功能。当构建或 Agent 运行足够繁重、需要持续数天时,更简洁的解决方案往往是彻底放弃管理笔记本的电源状态,将工作负载转移到始终在线的远程服务器上——那是一台从未被设计为需要睡眠的机器。对于在自己 Mac 上彻夜运行的场景,包裹命令,用 pmset -g assertions 验证断言,然后安心去睡觉吧。

常见问题

caffeinate -i 和 caffeinate -d 有什么区别?

-i 标志阻止系统空闲睡眠,同时仍允许显示器关闭,这正是后台 Agent 或构建任务所需的行为,也是笔记本上的正确默认选项。-d 标志阻止显示器睡眠,保持屏幕常亮,对无头任务而言会浪费电量。夜间终端工作请使用 -i,仅在显示器本身必须保持常亮时(例如监控仪表板)才使用 -d。

运行 caffeinate 需要 sudo 或管理员权限吗?

不需要。caffeinate 无需安装,也无需管理员权限,因为它使用的是 IOKit 的公开电源断言 API——这与 Xcode 等应用保持 Mac 唤醒所使用的官方机制相同。任何用户都可以直接在 Terminal 中运行它。它内置于 macOS 的 /usr/bin/caffeinate,自 OS X 10.8 起便已如此,无需安装任何内容,也无需授予任何提升权限。

关闭 Terminal 窗口后 caffeinate 会怎样?

断言会立即消失。由于电源管理断言存活于 caffeinate 进程内部,关闭或崩溃 Terminal 窗口会终止该进程并释放断言,使 Mac 恢复空闲睡眠。要在窗口关闭或崩溃后仍能存活,请在 tmux 中运行任务,并在会话内用 caffeinate 包裹命令,这样断言就绑定到了一个独立于 Terminal 的分离进程上。

如何让 caffeinate 只运行固定的小时数?

使用 -t 标志并以秒为单位指定超时时间。例如,caffeinate -i -t 28800 会阻止空闲睡眠恰好八小时,然后自动退出并释放断言。当你希望设定固定的时间窗口而非将断言绑定到特定命令的生命周期时,这个选项非常有用。若不使用 -t 且不包裹实用程序,裸 caffeinate 会一直运行,直到你手动按 Ctrl+C 停止。

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — self-hosted, with full data ownership.

Star on GitHub

We use cookies to improve your experience. By using our site, you accept cookies.