I went a step further. I never want my MacBook to sleep, not even when I close the lid, unless I tell it to explicitly, so I want to have full control about this behavior. If I do so, I also want to make sure that it can sleep, as I experienced a few times that it should sleep, but it actually didn't sleep, because some process was preventing sleep. On top of that, I want it to run a script on shutdown as well as on sleep, for the latter I can use the Sleep Watcher, so this solution adapts it for the former case.
First I run:
sudo pmset -a disablesleep 1
sudo pmset -a displaysleep 0
sudo pmset -a sleep 0
Now the Mac will run forever, even when closing the lid. Nice to carry it around without AC power or whatever while its doing some tasks, or just being ready without any delay.
Then I put these aliases into my .zshrc
:
alias cansleep="test ! $(pmset -g assertions | grep SystemSleep | grep -v 0)"
alias sleepnow="sudo sh -c 'pmset -a disablesleep 0 && pmset sleepnow && pmset -a disablesleep 1'"
alias gosleep="test cansleep && sleepnow || open -a 'Activity Monitor'"
alias poweroff='test -x "$HOME/.sleep" && "$HOME/.sleep"; osascript -e '"'"'tell app "System Events" to shut down with state saving preference'"'"
alias reboot='test -x "$HOME/.sleep" && "$HOME/.sleep"; osascript -e '"'"'tell app "System Events" to restart with state saving preference'"'"
From now on I start to control the boot and sleep behavior from the terminal exclusively:
- sleepnow: Try to sleep (similar behavior to closing the lit before the changes, a process could prevent sleep)
- gosleep: Check if you can sleep, if not, open the Activity Monitor to show you sleep-preventing processes, otherwise go sleep (a successful sleep is indicated by the screen turning black)
- poweroff: Graceful shutdown (as if you would shutdown from the apple menu as
shutdown
is not graceful), poweroff
will also try to run the .sleep
script, making its behavior like sleep while using the Sleep Watcher for consistency
- reboot: Like
poweroff
, but graceful restart. Also runs the .sleep
script
As you can see, I also wanted to include my personal routines prior sleeping that I trigger using the Sleep Watcher. Things like turning off bluetooth, now it's turned off prior shutdown or reboot as well.
This is a result of transitioning to powering off my MacBook whenever I want to put it into the bag, because despite checking for sleep preventing processes I have to admit, the solution is still error prone and I ended up with a hot device in the bag. I think Apple did a terrible job here. A closed lid should end up with deep sleep within the next 5 minutes, but Apple allows processes to prevent sleep, so the risk of slowly damaging your device through overheat is great.
Lastly, to avoid the required password on sleepnow
, I can take Randomblock1's approach and run this in order (line by line):
export ME="$USER"
sudo -E su
echo "$ME ALL=(ALL) NOPASSWD: /usr/bin/pmset" > /private/etc/sudoers.d/pmset
and use
alias sleepnow="sudo pmset -a disablesleep 0 && pmset sleepnow && sudo pmset -a disablesleep 1"
instead. You need to have the su
account enabled for that approach. Alternatively sudo visudo
works for that as well. A reboot is required to source the sudoers again.