Keep your Mac awake until a Terminal command or AI agent finishes
Put caffeinate -i in front of the command: caffeinate -i npm run build keeps the Mac awake exactly as long as the build runs, then lets it sleep. The same works for ffmpeg, rsync or an AI coding agent you start from Terminal. If the command is already running, find its process ID with pgrep -f and run caffeinate -i -w with that number in another window. SleepPilot can also wait for a running command and tell you when it’s done.
Updated · commands checked on macOS 27.2
Why long jobs stop
macOS puts the Mac to sleep after a while without user activity: no typing, no mouse, no trackpad. Unless the job itself (or something else) holds a power assertion, the Mac can fall asleep while a build, an encode or an AI agent is still working. You can check: while the job runs, see whether it appears in pmset -g assertions. Once the Mac sleeps, the job stops until it wakes, and connections it had open, such as a download or an agent’s requests to a server, can time out.
Starting the command
Write caffeinate -i in front of what you’d normally type:
caffeinate -i npm run build caffeinate -i ffmpeg -i input.mov output.mp4 caffeinate -i rsync -a ~/Projects/ /Volumes/Backup/Projects/
For an AI coding agent you run in Terminal, do the same with the command that starts it. caffeinate starts the command, holds the Mac awake while it runs and exits when it exits, with the same exit status. When we tried caffeinate -i sleep 3, pmset -g assertions showed “caffeinate asserting on behalf of ‘sleep’”.
For several commands in a row, wrap them in one shell:
caffeinate -i sh -c "npm run build && npm test"
A command that’s already running
You started the job, then realised it will take hours. Don’t stop it; point caffeinate at it.
- Open a new Terminal window and run
pgrep -fwith part of the command line, for examplepgrep -f "npm run build". It prints the process ID (PID). - Run
caffeinate -i -wfollowed by that PID, for examplecaffeinate -i -w 12345. - Run
pmset -g assertions. The caffeinate entry should say asserting on behalf of Process ID and your number. - When the command finishes, caffeinate exits too and the Mac can sleep on its normal schedule.
pgrep -f "npm run build"
caffeinate -i -w 12345
What pmset -g assertions showed for caffeinate -i -w on our Mac (shortened):
pid 53797(caffeinate): […] 00:00:00 PreventUserIdleSystemSleep named: "caffeinate command-line tool" Details: caffeinate asserting on behalf of Process ID 53796 Created for PID: 53796.
Check the number. We ran caffeinate -w with a PID that didn’t exist: it exited immediately, printed nothing and returned success, so the Mac was free to sleep.
In a script
Add this near the top of a shell script to keep the Mac awake until the script exits. $$ is the script’s own process ID:
caffeinate -i -w $$ &
We tested it: the assertion appeared “on behalf of Process ID” the script’s PID and was gone once the script ended.
With SleepPilot
SleepPilot (Mac App Store) does this without the PID. Click the moon in the menu bar, choose Until done… and pick the command from the list: it shows commands running in Terminal that were started from a shell, such as builds, ffmpeg, rsync, npm or an AI coding agent. When the command ends, SleepPilot lets the Mac sleep as usual and sends a notification, so you know it’s finished.
From Terminal or a script, these links do the same:
your-command & open -g "sleeppilot://wait?pid=$!" open -g "sleeppilot://start?minutes=90" open -g "sleeppilot://stop"
The first starts your command in the background and asks SleepPilot to wait for it ($! is the PID of the command just started). The second keeps the Mac awake for 90 minutes, the third stops. open -g leaves SleepPilot in the background.
Questions
Does the Mac sleep again when the command finishes?
Yes. The man page says the assertion lasts for the duration of the command (or until the process you passed to -w exits). After that the Mac goes back to its normal sleep settings.
Will the display stay on?
Not with -i: the screen turns off on its usual timer while the Mac keeps working. Add -d if you want to watch the output.
Can I close my MacBook’s lid while it runs?
Only in closed-display mode (power, external display, keyboard and mouse). Otherwise closing the lid puts the Mac to sleep and the command stops with it. Lid closed.
Does an SSH session keep the Mac awake?
Partly. pmset -g showed ttyskeepawake 1 on our Mac; the man page says this prevents idle sleep while a tty, such as a remote login session, is active, and counts a tty as inactive once it has been idle longer than the sleep timer. For a long job, start it with caffeinate -i anyway.
What if pgrep prints several numbers?
More than one process matches. Make the pattern more specific, or use pgrep -n to get only the newest one. caffeinate -w takes a single PID.
Sources
- caffeinate(8) man page
- pmset(1) man page
- IOPMLib.h: power assertion types — Apple open source