I've been looking into running a few cleanup commands when a user logs out, however the old logout hook feature, although still functioning, has been deprecated for some time now so may not be with us for much longer.
Unfortunately, although launchd
provides a convenient alternative to login hooks, there is no such obvious replacement for logout hooks.
I've already experimented with creating a shell script that is launched on login, and simply sleeps until a kill signal is received, however this doesn't seem to work (the script never receives the signal during normal operation).
Otherwise I'm not sure what the best way to run a quick command on logout would be? I know there are some third party utilities that can do it, but is there a "correct" way to do this anymore?
Best Answer
It seems that Apple isn't interested in a logout hook replacement, as they closed my issue inquiring about one.
However, one of the improvements in Yosemite is that launchd now properly sends signals down to shell scripts. What this means is that you can now do a log-out task like so:
Here's an example logout.sh:
This will simply sleep (asynchronously, doing it synchronously without the ampersand doesn't seem to work) until it receives one of the trapped signals, at which point it will execute the
onLogout
function.All you need to do is launch that script using a
RunAtLoad
launch agent or launch daemon and it will run at log-out or shutdown, though it's important to bear in mind that tasks only have a limited amount of time to complete before they are killed instead, so this shouldn't be used to run anything that takes a long time, or requires a network connection that could be delayed etc.Of course this is of no use to anyone on Mavericks or earlier, but under Yosemite this now seems to work as expected; so I was actually doing it right in the first place,
launchd
just wasn't sending the signals properly :)NOTE: For this to work the shell scripts seems to need to be executed directly by launched, i.e - it shouldn't invoked via
sh
. So if it were placed in~/Library/Scripts/foo.sh
your program arguments might look like: