10

How can one configure MacOS (10.8 or higher) to automatically and immediately call a user-designated script (probably a bash script) upon the user closing the display lid of a MacBook Air or Pro?

Details.

I want to do this because in some scenarios my MacBook Air 2013 running 10.8.5 does not immediately sleep/lock the screen upon lid close (possibly because a VPN client is trying to open a connection). As such, I want the system to immediately execute a script which calls this screen-saving-and-locking procedure upon lid close. However, I don't know how to call scripts upon display-lid closing.

0

4 Answers 4

9

There does not seem to be a way for a program to get notified when the lid is closed. However, the state of the lid can be monitored periodically (and in this particular case, every second) and actions taken based on the lid state.

I do not know of any program that can provide a complete solution for your need, but you can use the following information to build a solution yourself.

  1. Download this clamshellstate.pl perl script

  2. You can run it in Terminal (under /Applications/Utilities) like:

    ./clamshellstate.pl 1  
    

to get an output like "Open" or "Closed" indicating the current lid state

  1. Create a shell script like (substitute script-to-run with a shell script you'd like to run):

    ./clamshellstate.pl 1 | grep Closed > /dev/null && *script-to-run*
    
  2. Configure this script to run once every second using launchd.plist. Or use Lingon to easily configure launchd.plist.

Note: Instead of clamshellstate.pl, you can also use the following command in Terminal:

ioreg -r -k AppleClamshellState | grep AppleClamshellState | cut -f2 -d"="

to get a "Yes" for the closed state and a "No" for the open state.

3
  • 1
    Need to run a script upon lid close, not upon sleep. I specifically differentiate lid-close vs sleep because of the delay that can occur between close and sleep (I've experienced said delay emprically; above reference seems to confirm - "about 15 [seconds]") causing an insecure access if someone (say a thief) were to grab my MacBook seconds after I close it (reasonable for someone at the airport for a "hit and run" theft), open it up, and reset the password for the logged-in account. Commented Oct 7, 2013 at 19:16
  • I've updated the answer, but you'd need to do some scripting work to develop a complete solution.
    – M K
    Commented Oct 7, 2013 at 20:21
  • Terminal command should be: ioreg -r -k AppleClamshellState | grep '"AppleClamshellState"' | cut -f2 -d"="
    – Lei Zhang
    Commented Mar 23, 2019 at 6:07
4

You could also try using SleepWatcher. See the readme for instructions:

1. Install the SleepWatcher software:

$ sudo mkdir -p /usr/local/sbin /usr/local/share/man/man8
$ sudo cp ~/Desktop/sleepwatcher_2.2/sleepwatcher /usr/local/sbin
$ sudo cp ~/Desktop/sleepwatcher_2.2/sleepwatcher.8 /usr/local/share/man/man8

2. Read the man page and think about the features of SleepWatcher you want to use:

$ man sleepwatcher

3. Write small shell scripts that perform the actions you want to trigger by SleepWacher and test them.

4. Test your scripts in combination with SleepWatcher, started in the foreground in a Terminal window, e. g.:

$ /usr/local/sbin/sleepwatcher --verbose --sleep /path/to/your/sleepscript --wakeup /path/to/your/wakeupscript ...

5. Put your SleepWatcher command line into a launchd agent configuration file. As an example you can use one of the plists from ~/Desktop/sleepwatcher_2.2/config. For more information about launchd and its configuration, see the man pages for launchd and launchd.plist and http://developer.apple.com/macosx/launchd.html.

6. Copy your launchd agent configuration to /Library/LaunchDaemons or ~/Library/LaunchAgents, depending on whether you need a system wide daemon or a user agent.

7. Load the launchd agent configuration using launchctl (see examples above and the launchctl man page).

1
  • sleepwatcher is also available via MacPorts. Commented Dec 9, 2013 at 20:13
2

You could try using the ControlPlane app which can act on various state changes on your Mac including whether the lid is closed or not.

Also it is possible to use Hammerspoon to activate specific scripts on waking and sleeping as mentioned in my answer to another question. The lua scripts could be augmented to check for the lid state using the ioreg -r -k AppleClamshellState test mentioned in M K's answer here.

0

There are suggestions about how to get status here: Mac OS X - Bash script if statement based on system status

And then you might call a script from launchd.plist every so many seconds... Something like this. Not sure about how to run the shutdown as root without entering a password (when the lid is closed!)

#!/bin/bash
#power down on close lid

clamshell_status=if ioreg -r -k AppleClamshellState | grep '"AppleClamshellState"' | cut -f2 -d"="

if [[ ${clamshell_status} == "YES" ]]
then
    shutdown -h now
fi
      

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .