手搓一个合盖不休眠:三条命令加一个菜单栏开关
不用装第三方 App,用 pmset + sudoers 白名单 + SwiftBar 插件,把「合盖继续跑」搭出来。附电量看门狗,以及手搓版和付费版各缺什么。
正文
说明:这篇是手搓方案,和昨天发布的 LidRun 形成对照。
LidRun 卖 9 美元解决的那件事,用三条命令也能搭出来,而且不用装任何第三方 App。下面是完整版,照着敲能跑。它没有定时器和温度看门狗,但核心那个「合盖不断」的功能是齐的。
先弄清代价
macOS 允许应用在合盖时保持唤醒,靠的是 pmset -a disablesleep 1。这个开关是全局的,插电和用电池都生效,一旦打开,机器不会自己睡。
所以风险很直白:合盖运行散热差,塞进包里容易烫;忘了关就一直耗电。手搓版没有内置安全网,安全网得自己做,这也是后面第三步要写电量看门狗的原因。
第一步:只放行两条命令
不要给整个终端免密。给 sudo 一个白名单文件,只放行那两条 pmset 命令。
sudo visudo -f /etc/sudoers.d/disablesleep
粘进去:
%admin ALL=(root) NOPASSWD: /usr/bin/pmset -a disablesleep 0, /usr/bin/pmset -a disablesleep 1
写完验证一下,不出声就是成功:
sudo -n /usr/bin/pmset -a disablesleep 0
sudo visudo -c -f /etc/sudoers.d/disablesleep
这里有个设计取舍值得说明。授权的是 pmset 命令本身,不是某个包装脚本。哪怕脚本被人改写,攻击者也只能拿到这两条命令的执行权,拿不到 root。比 NOPASSWD: ALL,也比「授权一个放在家目录、之后可能被任意篡改的脚本」安全得多。
用 visudo 而不是直接写文件,是因为它会校验语法。sudoers 写错一个字符就可能把 sudo 锁死,那时候修起来很麻烦。
第二步:包一个开关脚本
直接敲 pmset 太麻烦,包成 on/off 两个参数:
sudo tee /usr/local/bin/disablesleep-toggle > /dev/null <<'EOF'
#!/bin/bash
set -e
case "$1" in
on) exec /usr/bin/sudo -n /usr/bin/pmset -a disablesleep 1 ;;
off) exec /usr/bin/sudo -n /usr/bin/pmset -a disablesleep 0 ;;
*) echo "usage: disablesleep-toggle on|off" >&2; exit 2 ;;
esac
EOF
sudo chown root:wheel /usr/local/bin/disablesleep-toggle
sudo chmod 755 /usr/local/bin/disablesleep-toggle
脚本本身也放在系统目录、归属 root,普通用户改不了。配合上一步的白名单,整条链路上没有需要输密码的地方。
第三步:菜单栏上放个开关
命令行能用,但你不会每次都开终端。用 SwiftBar 把它变成菜单栏图标。
brew install --cask swiftbar
首次启动会让你选插件目录。把下面这段存成 disablesleep.10s.sh,文件名里的 10s 就是刷新间隔,然后 chmod +x:
#!/bin/bash
# ~/.swiftbar/disablesleep.10s.sh
# 路径按你选的插件目录来
STATE=$(/usr/bin/pmset -g | /usr/bin/awk '/SleepDisabled/{print $2}')
# 电量看门狗:低于 20% 自动恢复正常睡眠,防止在包里耗到关机
BATT=$(/usr/bin/pmset -g batt | /usr/bin/grep -Eo '[0-9]+%' | /usr/bin/head -1 | /usr/bin/tr -d '%')
if [ "$STATE" = "1" ] && [ -n "$BATT" ] && [ "$BATT" -lt 20 ]; then
/usr/local/bin/disablesleep-toggle off
STATE=0
fi
[ "$STATE" = "1" ] && echo "☕" || echo "💤"
echo "---"
if [ "$STATE" = "1" ]; then
echo "合盖不休眠:已开启 · 注意散热 | color=red"
echo "恢复正常睡眠 | bash=/usr/local/bin/disablesleep-toggle param1=off terminal=false refresh=true"
else
echo "合盖不休眠:已关闭 | color=green"
echo "开启(合盖继续跑)| bash=/usr/local/bin/disablesleep-toggle param1=on terminal=false refresh=true"
fi
echo "---"
echo "刷新 | refresh=true"
装好之后,状态栏常驻一个图标:☕ 表示不休眠,💤 表示正常。点开直接切换,切完立刻刷新状态。
图标本身就是安全绳。你能一眼看出自己是不是忘了关,这比任何日志都管用。
第四步:验收
三件事做完再放心合盖。
- 点菜单栏图标切到 ☕,
pmset -g里SleepDisabled应该变成 1。 - 合盖,等两分钟,再用另一台设备 ping 它,或者看正在跑的任务有没有中断。
- 拔掉电源,把电量阈值改成 50% 试一次,确认看门狗会自己关掉开关。
第三步别跳过。看门狗写错了,你可能在包里发现一台烫的、开不了机的 MacBook。
手搓版缺什么
定时器(跑 2 小时自动停)、仅充电时才保持、温度看门狗、任务结束自动释放、活动日志。这些都能自己加,但加到第三个你就会发现自己在维护一个小项目:要处理睡眠唤醒、要防重复触发、要写日志轮转。
LidRun 卖的其实就是这些。核心那条命令是免费的,配套的约束是它的产品。
如果你只是偶尔出门前想让任务跑完,上面这套够用。如果你天天把 agent 丢在机器上过夜,花 9 美元省掉维护成本更划算。
本文由「策思路 C456」(c456.com)团队撰稿。
复制成功后将正文粘贴到公众号后台即可发布