Notes on Apple’s Under-Documented LaunchD
Start triggers fire regardless of other conditions
For example, StartOnMount=true will cause the job to start when anything is mounted even if other conditions, e.g. QueueDirectories, say the job should not run
Rhythm of repeating jobs
The StartInterval timer begins ticking at the moment the plist is loaded. If something like QueueDirectories is preventing the job from running initially, but the queue becomes available, the job will not be started until the StartInterval timer expires. The StartInterval timer starts over when the job exits, so a 20 second job with a 10 second StartInterval will run every 30 seconds.
Start Triggers and
If a trigger such as
<StartOnMount> causes the job to run, it doesn’t
<StartInterval> timer. If it was about to expire when the
Trigger happened, the job may run again immediately.
<ThrottleInterval> is about handling failures
<ThrottleInterval> says how long to wait if the job fails. If launchd
thinks the job succeeded,
<ThrottleInterval> will be irrelevant.
<ThrottleInterval> to zero for short
The console will say, “ThrottleInterval set to zero. You’re not that important. Ignoring.” But in fact it doesn’t ignore your setting: it stops trying to respawn the job when it exits in less than 10 seconds.
<WorkingDirectory> is a soft error
If you specify a non-existent
<WorkingDirectory>, the job runs in /
If you set
<QueueDirectories> and launchd sees that the directories are
not empty after the job runs, it considers that to be a failure and
runs the job again after the
<ThrottleInterval> expires. Therefore, if
you’re trying to set up a repeating job that runs only when a given
directory exists, you can’t use
<QueueDirectories> for that purpose.
<WatchPaths> will be triggered by disk mounts/unmounts
You can use this to respond when a particular directory has gets an image mounted/unmounted on it. This works regardless of whether the directory exists before/after the mount/unmount.
Loading and unloading with
If you unload a plist with
-w and then subsequently try to load it without
launchctl will just tell you “Nothing found to load.”
I’m not sure exactly what this implies yet.