Keep MacBook running with lid closed for specified duration

10,225

Solution 1

Github user iccir has made a very handy little menubar app called Fermata that does exactly what you want: keeps a MacBook awake with the lid closed, and allows you to set a timeout duration.

I just tried it on Mojave (10.14.2) and it worked great for me. https://github.com/iccir/Fermata

Solution 2

It's not ideal, but here's a solution. To prevent the laptop from sleeping when the lid is closed and you're running on battery, run the following commands:

sudo pmset -b sleep 0; sudo pmset -b disablesleep 1

To re-enable laptop sleeping when the lid is closed and you're running on battery, run the following commands:

sudo pmset -b sleep 5; sudo pmset -b disablesleep 0

The "5" in the second set of commands represents the number of minutes before sleeping when on battery; adjust as desired for your laptop.

This is a bit dangerous, since if you forget to re-enable your settings, the laptop will never sleep when on battery. Because of this, I've written a shell script to automatically re-enable the settings:

#!/bin/bash
#***************************************************************************
#*** noz - prevent laptop from sleeping when lid is closed
#***************************************************************************

#***** set some defaults *****
BATTERY_SLEEP=5 # in minutes
DEF_WAKE_LEN=300 # in seconds

#***** determine timeout value *****
timeout_len=${1:-$DEF_WAKE_LEN}

function prevent_sleep() {
    echo
    echo -n "Preventing sleep for $timeout_len seconds; press <enter> to continue..."

    sudo pmset -b disablesleep 1
    sudo pmset -b sleep 0
}

function enable_sleep() {
    # $1: <enter> = 0, timeout = 1, Ctrl-C = undef

    #----- insert a newline for timeout or Ctrl-C -----
    if [[ ${1:-1} -eq 1 ]]; then    echo; fi
    echo "Restoring previous battery sleep setting: $BATTERY_SLEEP"

    sudo pmset -b disablesleep 0
    sudo pmset -b sleep $BATTERY_SLEEP

    #----- sleep on timeout only -----
    if [[ ${1:--1} -eq 1 ]]; then   sudo pmset sleepnow; fi
    exit
}

#***** prevent it from sleeping *****
prevent_sleep

#***** trap Ctrl-C *****
trap enable_sleep INT

#***** wait for an enter *****
read -t $timeout_len
rc=$?

#***** re-enable normal sleep *****
enable_sleep $rc

The shell script will disable sleeping until you hit the Enter key, at which point it will re-enable the sleep settings (alternately, you can hit Ctrl-C and achieve the same thing). It will also set a timeout (defaults to 300 seconds/5 minutes) after which the sleep settings will automatically be re-enabled, and the laptop will be forced to go to sleep. While this would be a pain if you're using your laptop in a meeting, it will be a lifesaver if you forgot and put your laptop in your bag to go home.

Astute readers will note that these commands require sudo; sadly, that's unavoidable AFAIK. What I've done on my system is to make it so that I don't have to enter my password to run pmset as root. To do that, edit the sudoers file (sudo visudo) and add this line:

joe ALL=(ALL) NOPASSWD: /usr/bin/pmset

replacing "joe" with your username. You could probably achieve the same result (i.e. running the script without having to enter your password) by running the shell script SETUID, but I don't like doing that; opening up this one command via sudoers seems less risky to me.

To run the script, stick it in a directory on your PATH and invoke it as such:

$ noz [<timeout in seconds>]

When you get to where you're going, simply hit Enter or Ctrl-C and you're good to go. And if you forget about it, it will automatically reset and sleep.

There's probably a way to achieve all of this via AppleScript, so that you can then assign it a hot key and what not; I'll try that if I even get tired of running this from the command line.

Share:
10,225

Related videos on Youtube

CaptainProg
Author by

CaptainProg

Updated on September 18, 2022

Comments

  • CaptainProg
    CaptainProg almost 2 years

    Occasionally it's useful to leave a MacBook running for an hour or so to complete updates or some lengthy data analysis at the end of the day. I'd like to be able to close the lid of the MacBook or turn off the screen to prevent unnecessary light pollution.

    I have previously used two apps, Caffeine and NoSleep, to keep a MacBook awake.

    • Caffeine allows you to specify a duration to keep the MacBook awake for, but closing the lid puts the laptop to sleep.
    • NoSleep allows you to close the lid of the laptop (which turns off the screen, keeping any processes running), but you cannot specify a timeout duration.

    I'm looking for a solution that both allows the user to close the lid and specify a timeout duration. I don't want to leave the laptop running all night; usually just 30 minutes to an hour.

    Any solutions?

  • CaptainProg
    CaptainProg over 8 years
    NoSleep is working for me as advertised; however, what I need is the ability to have the system power-down after a specified period of time, which it does not have. Perhaps this should be a feature request for NoSleep, but I'm just wondering if anything already exists. As I'm using a laptop, having to connect all that hardware and then run Caffeine is a little too unwieldy to make this a viable solution.
  • CaptainProg
    CaptainProg over 7 years
    As far as I can tell, this app doesn't let me close the lid - at least, it doesn't work on my mid-2014 MacBook Pro. If I close the lid, the system sleeps.
  • Daniel Que
    Daniel Que almost 6 years
    Thanks! Now that InsomniaX is no longer maintained, and doesn't work on 10.13 (for me), this is the only option left.