◆

Mac 设置显示器关闭但不进入睡眠

2024-11-18 07:220

场景

mac 电脑在一段时间内不使用会自动关闭显示器,但有那么一个需求,再关闭显示器后,使用 keyboard maestro 写了个程序自动唤起电脑,但是总是无法执行

解决方法

打开设置-电池-电池-取消勾选-如果可能,使硬盘进入睡眠

mac设置电脑显示器关闭但不进入睡眠

打开设置-电池-电源适配器-勾选前 2 个,使硬盘进入睡眠

mac设置电脑显示器关闭但不进入睡眠

显示器关闭 ≠ 系统睡眠

这两件事在 macOS 里是分开控制的,搞清楚区别才知道该调哪个开关。

显示器睡眠(display sleep) — 屏幕背光关掉,但 CPU、内存、网络全部照常工作。所有进程继续运行,SSH 能连上,定时任务照跑。这是我们想要的状态。

系统睡眠(system sleep) — 整机挂起,CPU 停止执行,内存内容保持供电(这叫 S3 睡眠),网络断开或者进入极低功耗的唤醒代理模式。所有进程被冻结,脚本、定时任务全部停摆。

安全睡眠(hibernate) — 把内存内容写到磁盘再断电,唤醒时从磁盘恢复。笔记本电量耗尽前会自动进入这个状态。恢复慢但不掉数据。

正文的需求是「显示器关掉但程序继续跑」,也就是要允许显示器睡眠、禁止系统睡眠。keyboard maestro 的定时脚本执行不了,就是因为系统整机睡下去了,脚本没机会运行。

电源设置里各选项的实际含义

系统设置 → 电池 下面分「电池」和「电源适配器」两组,因为插电和用电池的策略应该不一样。里面的关键选项:

防止显示器关闭时电脑自动进入睡眠 — 这是最直接对上需求的一项,只在「电源适配器」标签下有(用电池时不允许,为了续航)。勾上之后显示器关闭时系统保持唤醒。这就是正文说的「勾选前 2 个」里最关键的那一项。

如果可能,使硬盘进入睡眠 — 让机械硬盘停转省电。SSD 机型上这项意义不大(SSD 没有马达),但它会影响系统的整体功耗策略判断。正文在「电池」下取消勾选它,是为了减少一层可能导致系统降入低功耗状态的因素。

唤醒以供网络访问(Wake for network access)— 网络请求到达时唤醒机器。远程访问、时间机器网络备份需要它。如果你的自动化脚本是被外部触发的(比如收到 HTTP 请求),这项必须开。

电池电量不足时自动睡眠 — 保命机制,不要关。

显示器关闭时间 — 这是滑块控制的,决定多久无操作后关屏。设成「永不」会一直亮着,费电且烧屏(OLED 屏),不建议。合理的做法是让屏关掉、系统不睡。

更可靠的做法:caffeinate

图形界面的设置是全局的、长期生效的,而「不让系统睡」这个需求通常是临时性的——跑一个长时间的构建、导出视频、下载大文件。为此永久关掉睡眠既费电又没必要。

macOS 自带 caffeinate 命令专门做这件事:

# 阻止系统睡眠,直到你按 Ctrl+C
caffeinate

# 阻止睡眠 3600 秒(1 小时)后自动结束
caffeinate -t 3600

# 阻止睡眠直到某个命令跑完,命令结束后自动解除
caffeinate -i npm run build

最后那个用法最实用:caffeinate 后面直接跟命令,它会 fork 出子进程执行,期间保持唤醒,命令一结束限制自动解除。不用记着手动关。

几个参数的区别值得记清楚,因为它们对应不同层级的「唤醒」:

  • -d — 阻止显示器睡眠(屏幕一直亮)
  • -i — 阻止系统空闲睡眠(屏幕可以关,系统不睡)← 这个对应本文的需求
  • -m — 阻止磁盘进入空闲状态
  • -s — 阻止系统睡眠,但只在接通电源时生效
  • -u — 模拟一次用户活动(等于「假装你动了鼠标」),配合 -t 用
  • -w <pid> — 等某个进程结束后自动解除

所以「显示器关闭但系统不睡」的准确命令是:

caffeinate -i

想让它在后台一直挂着:

caffeinate -i &

记下返回的 PID,需要解除时 kill <PID>。或者干脆:

pkill caffeinate

查看当前是什么在阻止睡眠

有时候机器该睡的时候不睡,或者不该睡的时候睡了,可以用 pmset 查诊断信息:

# 看当前有哪些进程持有「阻止睡眠」的断言
pmset -g assertions

输出里会列出 PreventUserIdleSystemSleep、PreventUserIdleDisplaySleep 这些断言以及持有它们的进程。视频播放器、下载工具、会议软件都会持有这类断言,这就是「放视频时屏幕不会自动关」的实现方式。

看完整的电源配置:

pmset -g custom

会分别列出 AC(插电)和 Battery(电池)两套配置的所有参数。对照着看比图形界面清楚,因为有些参数图形界面里没暴露。

看最近的睡眠/唤醒历史,排查「机器半夜自己醒了」这类问题:

pmset -g log | grep -E "Wake|Sleep" | tail -30

输出里会写明唤醒原因(Wake Reason),常见的有 EC.LidOpen(开盖)、RTC(定时唤醒)、XHC1(USB 设备活动)、GBAS(网络唤醒)。

用 pmset 直接改配置

pmset 也能改设置,而且比图形界面更精细。需要 sudo:

# 插电时:禁止系统睡眠(0 表示永不)
sudo pmset -c sleep 0

# 插电时:15 分钟后关显示器
sudo pmset -c displaysleep 15

# 电池时:10 分钟后系统睡眠
sudo pmset -b sleep 10

-c 是接通电源(charger),-b 是电池(battery),-a 是两者都改。

这里要提醒的是:sudo pmset -c sleep 0 是个持久性的系统级改动,会一直生效直到你改回来。它的效果和图形界面里勾「防止自动睡眠」类似,但更直接。设了之后记得知道怎么恢复:

# 恢复成 macOS 的默认电源配置
sudo pmset restoredefaults

我个人的取舍是:图形界面保持默认(该睡就睡),临时需求用 caffeinate。理由是持久性配置容易忘——设了之后几个月后发现机器一直不睡、电池损耗加快、发热,回头找原因很费时间。caffeinate 是显式的、有生命周期的,不会留下这种隐患。

定时唤醒:pmset schedule

正文提到用 Keyboard Maestro 定时唤醒电脑。其实 macOS 原生就支持定时唤醒,而且比软件方案可靠——它是固件层面的 RTC 定时器,即便系统在睡眠中也能生效:

# 每天 8:00 唤醒
sudo pmset repeat wake MTWRFSU 08:00:00

# 查看当前的定时计划
pmset -g sched

# 取消所有定时计划
sudo pmset repeat cancel

星期的字母表示:M=周一、T=周二、W=周三、R=周四、F=周五、S=周六、U=周日。

如果需要「唤醒后执行某个脚本」,正确的组合是:用 pmset repeat wake 负责唤醒,用 launchd(macOS 的定时任务系统)负责执行。launchd 的任务配置里可以设 StartCalendarInterval,并且它有个重要特性:如果任务的执行时间点机器在睡眠中,唤醒后会补跑。这比 cron 可靠(cron 错过的时间点直接跳过)。

一个最小的 launchd 配置示例,存成 ~/Library/LaunchAgents/com.wfly.mytask.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.wfly.mytask</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>/Users/wfly/scripts/mytask.sh</string>
    </array>
    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>8</integer>
        <key>Minute</key>
        <integer>5</integer>
    </dict>
</dict>
</plist>

加载它:

launchctl load ~/Library/LaunchAgents/com.wfly.mytask.plist

这套组合(pmset 定时唤醒 + launchd 执行任务)不依赖任何第三方软件,也不需要让系统一直保持唤醒,是最省电的方案。

💬留言板0

还没有留言,来发表第一条吧~

PAGE LOAD / LIVEMac 设置显示器关闭但不进入睡眠加载中