OS X application start/stop hook
Assuming answers to my clarification questions above are that you want:
- the script to run anytime a specific application is run, regardless of how or by what process or user, and
- the script to run in an asynchronous, non-blocking way (e.g. for logging purposes)
...there may be a few ways to do it. None I can think of are terribly elegant or turnkey and all require some sort of demonized process running as root which act to monitor the system for launch events.
Monitoring exec
calls via fs_usage
One possible way is to create a daemon (LaunchDaemon) which runs continuously, monitoring a running fs_usage
command for exec
events. You can see the kind of information you get by running the following command:
sudo fs_usage -f exec
Here's the relevant line when I opened Safari:
17:30:14.465075 posix_spawn /Applications/Safari.app/Contents/MacOS/Safari 0.000352 launchd.51630812
Here's the output when I opened ran open /Applications/Maps.app
from the command line:
17:35:51.594849 execve /usr/bin/open 0.003680 W bash.51635318
17:35:51.642212 posix_spawn /Applications/Maps.app/Contents/MacOS/Maps 0.003158 W launchd.51635324
Note that nearly all "Applications" (/Applications/*.app) are launched via posix_spawn
by launchd
and the file used to launch them is /Applications/FOO.app/Contents/MacOS/FOO
(where FOO
is the application's name). So, theoretically, you could have your LaunchDaemon monitoring this command and triggering your script whenever it outputs the path to the app you're monitoring:
sudo fs_usage -w -f exec | perl -lne 'm/.*posix_spawn +(.*?) +[0-9.]+ . launchd.\d+/sm && print $1'
Monitoring launchservicesd
via lsappinfo
I wasn't terribly happy with the above because it's kinda hacky, watching for filesystem events instead of the launching event that triggered them. And then I realized, "launchd
"! Enter Launch Services:
- launchservicesd(1) manpage
- lsappinfo(8) manpage
Leading to:
lsappinfo listen +all forever
And Voilà, you not only have launching, but also get notified when an app quits. The keys you care about are the following:
- kLSNotifyApplicationLaunch
- kLSNotifyApplicationBirth
- kLSNotifyLaunchFinished
- kLSNotifyApplicationDeath