# How can I make Mac OS X run a program before shutting down?

I am trying to get Mac OS X to save all my VirtualBox VMs when it reboots. I already have a script that does this, but I need OS X to run this script automatically before a reboot.

When Mac OS X reboots, does it run /sbin/reboot?

Or how else could this be achieved?

-
Duplicate question here: apple.stackexchange.com/questions/16825/… –  michaelmichael Jul 5 '11 at 14:08
That's not a duplicate. I don't want to know how to run a script or program when logging out. I want to know how to run a script or program when shutting down. –  Andrew J. Brehm Jul 5 '11 at 14:24
You're right. Not an exact duplicate. The answer in the linked question advises the user to place their script in /etc/rc.shutdown.local to run it when shutting down. It sounds like that's what you're looking for. –  michaelmichael Jul 5 '11 at 14:54
This site seems to make that claim: hints.macworld.com/article.php?story=20051013141919568 –  Andrew J. Brehm Jul 5 '11 at 15:10
The rc.shutdown.local method doesn't work. –  Andrew J. Brehm Jul 26 '11 at 17:56

Launchd sends an early warning of shutdowns to all scripts/daemons that have a StopService() subroutine. This gives your process the most time to clean up.

Just use launchd to start the script and have it run in the background until it's time to exit.

After the services that got the early warning are closing down, All processes get a SIGTERM signal a few seconds before the SIGKILL nukes them.

You could make a script that sleeps and traps SIGTERM to run your command when that time comes. You will have to see if that allows enough time in practice for the commands to execute. This avoids a little bit of coding, but not much - it's generally better to just make a daemon out of a shell script.

From a historical perspective - /sbin/reboot and runlevels never existed on Darwin / OS X and rc.shutdown is deprecated along with the rest of rc now that launchd is the boss. You might be able to use rc.shutdown on tiger or earlier (I don't have one of those images handy to check presently) Lion certainly has removed all vestiges of rc.d and init.d.

You might want to see if sleepwatcher would help in your case. I haven't used it in quite a while - but it certainly aims to solve your dilemma.

-
Turns out "deprecated" means "doesn't work". :-( –  Andrew J. Brehm Jul 26 '11 at 17:57
Yup - the warnings started on Tiger and i'd guess it went away with Leopard - it's hard to recall with all the Lion changes running around my brain. –  bmike Jul 26 '11 at 18:04
This really complicates matters and makes Mac OS X a very bad server platform. –  Andrew J. Brehm Jul 27 '11 at 12:37
launchd is fully capable to run scripts at shutdown. Perhaps I should edit out the history and leave that fact more clear. In what way does launchd fail your need to run a script at shutdown? –  bmike Jul 27 '11 at 14:26
I don't know how to make launchd run scripts at shutdown. I use launchd to start things at boot. –  Andrew J. Brehm Jul 27 '11 at 15:04

Although Apple recommends to use "launchd" the easiest is to create a shell script using for example Terminal's pico :

pico /Users/Shared/logoutHook.sh


The file can contain something like :

#!/bin/bash
say 'Hasta la vista baby!'


Then give exuction rights :

sudo chmod +x /Users/Shared/logoutHook.sh


Finally hook the script to the logout procedure :

sudo defaults write com.apple.loginwindow LogoutHook /Users/Shared/logoutHook.sh


If you start an other application, as I haven't tested this I think it might be useful to warn myself and you that :

• We might need to kill the shutdown signal to execute what we want ;

• Then send a new one (beware not to kill the signal send by our own
script)…

If you want to remove the hook :

sudo defaults delete com.apple.loginwindow LogoutHook


If using "launchd" the idea would be to capture the SIGTERM signal have a look at : /System/Library/LaunchDaemons/com.apple.shutdown_monitor.plist

-