Keep a Mac awake - even on battery with the lid closed. ARM & Intel.
brew tap ecc521/keepawake
brew install ecc521/keepawake/keepawake
sudo keepawake install
Or build from source with cd cli/keepawake && ./build.sh, then run
sudo ./keepawake install.
The one-time install step adds a sudoers rule permitting exactly two
commands (/usr/bin/pmset -a disablesleep 0/1). Remove both at any time with
sudo keepawake uninstall.
keepawake # run until Ctrl-C
keepawake -t 3600 # run for 1 hour, then stop automatically
keepawake -- ./backup.sh # run a command, stop when it exits
keepawake --battery 20 # release the hold at 20% battery; default 10
Whenever keepawake stops, the hold is released and normal sleep resumes.
The -d -i -m -s -u flags match caffeinate, so you can use keepawake in its
place and still cover ordinary display and disk sleep. Full CLI reference:
cli/keepawake/README.md.
Clamshell mode automatically sleeps, even with caffeinate, unless plugged into both an external display and charger.
The display requirement can be bypassed with a virtual display, but that does not satisfy the charging requirement.
The only available option (that I am aware of) here is pmset, to fully disable the sleep capability.
keepawake holds the system-wide SleepDisabled power-management setting, via
pmset -a disablesleep 1, for as long as the session lasts.
Setting it requires root, which is what the one-time sudo keepawake install
is for. It writes /etc/sudoers.d/keepawake:
%admin ALL=(root) NOPASSWD: /usr/bin/pmset -a disablesleep 1, /usr/bin/pmset -a disablesleep 0
SleepDisabled governs system sleep only. Display and disk sleep are
independent timers. keepawake also runs /usr/bin/caffeinate
internally (tied to its own lifetime via -w) to hold those assertions, so it can be used as a drop-in caffeinate replacement that guarantees full sleep prevention instead of sleep prevention only when plugged in and on AC power
An unattended device (car, backpack, etc) that is left running could easily overheat or run itself out of battery. The cutoffs here are conservative defaults, however are intended to reduce the risk of unexpected surprises.
--battery <pct>|none(default10): releases only on battery when battery drops below the specified percentage.--thermal none|serious|critical(defaultcritical): releases under thermal pressure.seriousis reached by ordinary heavy CPU/GPU work, but is likely a better choice for devices in enclosed areas.
Both locks reacquire immediately after battery / thermal pressure have dropped.
SleepDisabled is persisted to disk, so a run killed with kill -9 or lost to
a panic can leave it set. Any of these clears it:
keepawake --release # explicit
keepawake ... # any later run takes the hold, then clears it on exit
sudo pmset -a disablesleep 0 # directly, no keepawake involved
pmset -g reports SleepDisabled on its first line, which is also the answer
to "why won't this Mac sleep?".
- The hold is system-wide. It is one global setting, not a per-process
assertion. Concurrent sessions are fine: they share a
flock(2), and the last one out releases the hold, but that also means the last session ending clears a hold you set by hand outside keepawake.
./tests/run_tests.sh
Tests that take a real hold need the sudoers rule installed and skip cleanly without it. A physical lid close still has to be tested by hand.
MIT. See LICENSE.