Featured image of post MacBook 插电合盖不睡、用电池照常休眠

MacBook 插电合盖不睡、用电池照常休眠

- 用 Amphetamine + Power Protect 按电源状态切换 disablesleep

起因

MacBook 插着电源挂着 SSH、下载、编译或者跑 Agent,想合上盖子让它自己跑,结果一合盖,系统就睡了,任务全断。

我想要的效果是:

  • 插着电源:合盖不睡眠,任务继续跑;
  • 用电池:合盖照常休眠,别在包里把电池耗光。

原理

macOS 合盖时会强制睡眠,caffeinate 和 KeepingYouAwake 这类防休眠工具都挡不住。能挡住的只有系统级开关:

1
sudo pmset -a disablesleep 1

问题是这个开关是全局的,不区分电源。打开以后,用电池合盖也不会睡。所以需要一个工具在插电时打开、拔电时关闭它。这里用 Amphetamine + Power Protect:

工作原理

  • Amphetamine:Mac App Store 免费下载,无广告、无内购,支持按条件自动启动会话(Trigger)。
  • Power Protect:Amphetamine 官方配套脚本,需要单独安装。它让 Amphetamine 可以免密切换 disablesleep,并保证合盖状态下插拔电源时行为正确。

配置步骤

1. 安装 Amphetamine 并设为开机自启

  1. Mac App Store 搜索 Amphetamine 并安装。
  2. 打开后菜单栏会出现一个药丸图标。
  3. 点图标 → Preferences → General → 勾选 Launch Amphetamine at login。

Amphetamine 必须在运行,Trigger 才会生效。

2. 安装 Power Protect

  1. 在 Amphetamine 里手动启动一次合盖模式会话:会话选项中取消勾选 Allow system sleep when display is closed,然后启动。

  2. Apple Silicon 机型会弹出 Power Protect 提示,点 Learn More,按链接下载并安装。

  3. 安装时用 Touch ID 或管理员密码确认。

  4. 在终端验证是否装好:

    1
    
    sudo -n pmset -a disablesleep 0 && echo "OK:免密生效"
    

    输出 OK 说明成功;如果提示需要密码,说明没装成功。

安全性:Power Protect 只为 pmset -a disablesleep 1 和 pmset -a disablesleep 0 两条命令添加 sudo 免密规则,不能拿来提权,其他 sudo 操作照旧需要密码。可以用 sudo ls /etc/sudoers.d/ 找到对应文件,确认里面只有这两条命令。

3. 开启 Triggers

Preferences → Triggers → 勾选顶部的 Enable Triggers。

4. 创建“插电不睡”的 Trigger

点左下角 + 新建 Trigger:

  • Name:随意,例如 dont sleep when adapter plugin。
  • Criteria:点 +,选择 Battery & Power Adapter,双击编辑:
    • 滑块拖到最左边,或拖到 10% 左右当作保险;
    • ❌ 不要勾选 …or power adapter is connected;
    • ✅ 勾选 Only when power adapter is connected。
  • Additional Options:
    • ✅ Allow display to sleep:屏幕可以熄灭,省电也护屏,不影响任务运行;
    • ❌ Allow system to sleep when display is closed:不勾,这是合盖不睡的关键;
    • Allow screen saver to run after:无所谓。

最后点 Save。配置好之后大概是这样:

Trigger 配置示意

编辑完成后,条件列表里应该只有这一条:

CriterionValue(s)
Battery & Power AdapterOnly when power adapter is connected

常见坑:别用“或”逻辑

不要配置成“电量 ≥ 100% 或 电源已连接”。充满电后拔电,电量仍是 100%,条件继续成立,会话会在电池下保持不睡:

两种条件写法的区别

5.(可选)低电量保险

Preferences → Battery → 开启“电量低于 10% 时结束会话”之类的选项。万一哪次拔电后没恢复,也不会把电池耗光。

验证

状态切换(开盖即可测)

操作预期结果
插上电源菜单栏药丸图标变为激活状态
拔掉电源几秒内图标恢复为未激活

随时可以查看系统开关的状态:

1
pmset -g | grep -i sleepdisabled   # 1 = 合盖不睡,0 = 正常

插电时应该是 1,拔电后应该是 0:

终端验证

合盖实测

在终端跑一个持续任务:

1
ping 1.1.1.1
  • 测试 A:插电合盖。等 2 分钟后开盖,ping 没有中断就是成功 ✅

  • 测试 B:合盖状态下拔电。等 2 分钟后开盖,查看睡眠日志:

    1
    
    pmset -g log | grep -E "Sleep  |Wake  " | tail -5
    

    拔电之后的时间点有 Sleep 记录,说明电池下正常休眠 ✅

排查与还原

Trigger 不生效

  • 确认 Amphetamine 正在运行;
  • 确认 Enable Triggers 已经勾选;
  • 确认 Trigger 本身处于启用状态。

拔电后没睡

  1. 检查 sleepdisabled 是否仍是 1;
  2. 检查 Criteria 是否误用了“或”逻辑;
  3. 检查 Power Protect 是否装好,用第 2 步的免密命令测试。

完全还原

  1. 删除或停用 Trigger,退出 Amphetamine;

  2. 删除 /etc/sudoers.d/ 里 Power Protect 对应的文件;

  3. 执行下面的命令,确保合盖睡眠恢复:

    1
    
    sudo pmset -a disablesleep 0
    

注意事项

  • 合盖运行时散热比开盖差,长时间重负载的任务尽量放在通风的硬表面上,别放在包里或床上。
  • disablesleep 是全局开关,重启后依然保留。如果卸载 Amphetamine 前它是 1,记得手动改回 0。
  • 想用开源方案的话,Agent On 的逻辑和这套配置一致:插电禁用合盖睡眠,拔电立即恢复。
由 Hugo 强力驱动