OpenClaw 远程连接是如何让电脑不锁屏一直在工作的?
OpenClaw 自己没有"防锁屏"功能——让远程电脑一直在线不被系统休眠干掉,靠的是 操作系统层面 的电源管理配置。
- 根本问题:macOS/Windows/Linux 默认都会在空闲时进入休眠,系统的电源管理策略会直接挂起进程,Gateway 连接中断,远程控制失效。
- macOS 解法:
sudo pmset -a sleep 0全局禁休 +caffeinate -s进程级防睡 + LaunchDaemon 系统级自启,三层叠加 才能保证锁屏后服务不掉。 - Windows 解法:电源计划设"从不睡眠"只是第一步,还要关混合睡眠、禁用 USB 选择性暂停、组策略禁用待机状态 S1-S3,否则 硬件省电策略会偷偷断网。
- Linux 解法:
systemctl mask sleep.target suspend.target从 systemd 层面禁掉休眠路径,配合 logind.conf 忽略合盖/电源键事件,GNOME 只关屏不睡眠。
- 关键区分:LaunchDaemon(系统级,开机即跑)≠ LaunchAgent(用户级,登出即停),远程无人值守必须用前者。
- 验证标准:锁屏 30 分钟后 Gateway 日志仍有新消息进来,
pmset -g | grep sleep全显示 0,才算配置成功。
问题在哪
你在公司台式机上部署了 OpenClaw Gateway,回到家想用手机通过飞书远程让 AI 跑个任务。消息发出去了,对面没反应——因为电脑在你离开两小时后自动休眠了。
这不是 OpenClaw 的 bug,是操作系统的电源管理策略在按预期工作:空闲 → 休眠 → 进程挂起 → 网络断开。所有远程控制工具都面临这个问题,OpenClaw 也不例外。
那怎么解决?答案分三层,从浅到深,缺一层都可能翻车。
第一层:关掉系统休眠
最直观的操作——告诉操作系统"别睡"。
macOS 上两行命令:
sudo pmset -a sleep 0 disksleep 0
sudo pmset -a hibernatemode 0 standby 0 autopoweroff 0
pmset -a 的 -a 意思是 all,即电池和电源适配器两种模式下都生效。把 sleep、disksleep、standby 全设为 0,系统就不会主动进入休眠。
Windows 上走图形界面:设置 → 系统 → 电源和电池 → 睡眠设为"从不"。但这只改了当前电源计划,切换计划(比如从"平衡"切到"节能")需要重新配置。
Linux(systemd) 上更彻底——直接 mask 掉休眠目标:
sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
mask 的意思是"把这 个 target 的启动路径替换为 /dev/null",任何程序试图触发休眠都会失败。比 disable 更暴力,disable 只是取消自启,mask 是让它根本不能被激活。
第二层:进程级防睡 + 崩溃自愈
关了系统休眠还不够。macOS 有个叫 App Nap 的机制,会对"不活跃"的进程降频、限流。你以为电脑没睡,但 Gateway 进程被系统偷偷挂起了。
caffeinate 是 macOS 原生的防睡工具,给进程打一个"我正在忙"的标记:
/usr/bin/caffeinate -s /path/to/openclaw gateway --port 18789
-s 参数的意思是:屏幕可以关,但系统不能睡,网络必须保持活跃。这对远程连接至关重要——远程控制不需要屏幕亮着,但网络必须通。
更关键的配置是 LaunchDaemon。别用 LaunchAgent——LaunchAgent 是用户级的,你登出就停了。LaunchDaemon 是系统级的,开机就跑,不依赖任何用户登录会话:
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<dict>
<key>NetworkState</key><true/>
<key>Crashed</key><true/>
</dict>
<key>ProcessType</key>
<string>Interactive</string>
<key>ThrottleInterval</key>
<integer>0</integer>
这几个参数各司其职:
| 参数 | 作用 |
|---|---|
NetworkState: true | 网络恢复后自动重启服务 |
Crashed: true | 进程崩了自动拉起来 |
ProcessType: Interactive | 禁止 macOS 挂起/限流该进程 |
ThrottleInterval: 0 | 禁用 launchd 的节流机制,崩溃后立即重启不等间隔 |
Windows 侧也有类似陷阱。电源计划设了"从不睡眠",但高级电源设置里的"混合睡眠"、"USB 选择性暂停"、"无线适配器节能"是独立开关——混合睡眠会在休眠前把内存写到硬盘,这个过程一样会断网。这些全得关:
- 睡眠 → 允许混合睡眠:关闭
- 硬盘 → 关闭硬盘时间:0
- 无线适配器设置 → 节能模式:最高性能
- USB 设置 → USB 选择性暂停:已禁用
第三层:硬件触发器的最后一公里
即使前两层都配好了,还有一个坑:物理事件。
Linux 上合上笔记本盖子,logind 默认会触发休眠。不管你前面 mask 了多少 target,HandleLidSwitch=suspend 还在,合盖照睡不误。改 /etc/systemd/logind.conf:
HandleSuspendKey=ignore
HandleHibernateKey=ignore
HandleLidSwitch=ignore
HandleLidSwitchExternalPower=ignore
IdleAction=ignore
GNOME 用户还要加一步:
gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-type 'nothing'
gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-battery-type 'nothing'
GNOME 的电源设置独立于 systemd,不配这一层,桌面环境仍然会在空闲超时后触发休眠。
macOS 的 MacBook 也有类似的限制:合盖强制休眠是硬件级的,软件改不了。唯一例外是 clamshell 模式——外接显示器 + 外接电源时合盖不休眠。用 MacBook 跑 OpenClaw 的话,要么不合盖,要么插显示器。
附:Codex 的"运行时防止系统休眠"开关是怎么实现的?
如果你用过 Codex 桌面客户端,会在 Runtime 设置里看到一个开关——"运行时防止系统休眠"。勾上之后,即使你锁屏离开,Codex 也能继续干活。
它的底层原理其实和前面讲的 caffeinate 走的是同一条路——IOPMAssertion API。caffeinate 是苹果对这个 API 的命令行封装,Codex 则是直接在进程里调用它,创建电源断言(Power Assertion):
kIOPMAssertionTypePreventUserIdleSystemSleep // 防系统空闲休眠
kIOPMAssertionTypeNoDisplaySleep // 允许关屏但保持运行
光有电源断言还不够。真正让 Codex 在锁屏状态下"看见并操作"屏幕的,是两个额外的 macOS 权限:
| 权限 | 底层 API | 作用 |
|---|---|---|
| 屏幕录制 | CGDisplay API | 锁屏状态下读取帧缓冲,做 UI 元素识别 |
| 辅助功能 | Accessibility API (AXUI) | 遍历 UI 元素树 + 模拟键鼠输入 |
Apple 的 TCC (Transparency, Consent, and Control) 框架管理这些权限,用户必须手动在系统设置里授权,Codex 没法自己绕过。
所以 Codex 这个开关做的事情可以总结为:IOPMAssertion 接管电源管理 + Accessibility API 接管 UI 操控 + Screen Recording 实现锁屏感知。和前面手配 LaunchDaemon 的区别在于——Codex 把三层封装成了一个开关,你不用写 plist,点一下就行。
但有一样限制 Codex 也绕不过去:MacBook 合盖强制休眠是硬件级的,合盖之后 IOPMAssertion 也救不回来。这一点和前面第三层讲的一致。
怎么算配好了?
三个验证标准:
- 锁屏 30 分钟后,Gateway 日志里仍有新消息时间戳在更新
pmset -g | grep sleep(macOS)或systemctl status sleep.target(Linux)确认休眠状态为 disabled/masked- 从手机通过 IM 渠道发一条指令,Agent 能在 10 秒内响应
三层配置,缺一层都可能在你以为一切正常的时候掉链子。配好之后,OpenClaw 就是真正意义上的 7×24 数字员工了。