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.
exec calls via
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
launchd and the file used to launch them is
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'
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:
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: