macOS has several systems for running software automatically, of which three are accessible outside other apps and therefore suitable for running scripts of different kinds. Although long since deprecated, the standard Unix scheduler
cron is still available if you really must. LaunchServices also offers Login Items, but those are only launched once, when your Mac starts up. For general purposes, including running tasks which must occur at regular intervals, the primary mechanism is
launchd, with its control tool
Mac OS X 10.4 brought together the functions of a disparate group of Unix tools, including
watchdogd, into a single service manager
launchd, which is controlled by
launchctl. During startup, once the kernel is running and required kernel extensions have been loaded,
launchd is run with the process ID of 1, and it remains running until your Mac shuts down again.
Before you log in,
launchd runs services and other components which are specified in Property List files in the LaunchAgents and LaunchDaemons folders in /System/Library, then in /Library. Those in /System/Library are all part of macOS, owned by Apple, and now (macOS 11 and later) can’t be modified without unsealing the system, but those in /Library include many installed by third party products. As they’re run before the user logs in, they work for all users, so provide global services.
Once you have logged in,
launchd runs any services and other components specified in any LaunchAgent folder in ~/Library. Those are user-specific.
Launchd is best suited to background services, which use it the most. You don’t need any tools beyond a Property List or text editor to craft its configuration files, although Peter Borg’s Lingon and Soma-zone’s LaunchControl make them much more accessible. It’s also widely abused by malware, which often installs its own LaunchAgents and LaunchDaemons to ensure its persistence across reboots, and to perform services which it requires.
Uninstalling a LaunchAgent or LaunchDaemon is simply a matter of trashing its Property List from the appropriate folder – a task sometimes necessary when you’ve uninstalled an app which doesn’t clean up properly after itself. If software does need to install one or more Property Lists in any of these folders, then it should also provide an effective uninstaller to remove them when required.
LaunchAgent or LaunchDaemon?
Apple defines a LaunchDaemon as a general background service, without any form of GUI. Specifically, LaunchDaemons are not allowed to connect to the macOS window server. LaunchAgents do have access to the GUI, and to other system features such as locating the current user’s Home folder, but generally have more limited interfaces than do regular apps.
These Property List files contain keyed settings which determine what
launchd does with what. In Lingon and LaunchControl, these are presented in more understandable ways which should help you set them correctly. For example, the following property list, viewed in LaunchControl, runs my command tool
blowhole at startup and again every 3600 seconds, or one hour.
This equates to a property list containing just the following dictionary
For tasks running at regular intervals, the most important keys are:
- ProgramArguments, which tells
launchdwhat to run;
- RunAtLoad, which determines whether it is run whenever your Mac starts up;
- StartInterval, which sets the time interval between launches.
To run a GUI app as a LaunchAgent, set the ProgramArguments to the executable binary of the app, in its Contents/MacOS folder.
If you prefer, you can use the
launchctl command tool to dynamically configure LaunchDaemons and LaunchAgents, but Apple has been progressively limiting its capabilities, and now you’re generally better off using a property list, which is also less prone to error.
So long as you’re working with a small number of daemons/agents,
launchd isn’t that complex, and certainly not difficult to use. It can get messier when you need to know about other tasks. One example of this is when your Mac starts crashing or freezing at 0200 every morning, but the logs provide insufficient information to identify what has caused the problem.
Apple’s documentation on
launchd is very old now, but is still a valuable reference, as is TN2083.
launchd, launchctl, cron, and
crontabs are fully documented in their
man files. The best overall guide to
launchd is Soma-zone’s launchd.info, which explains how to make your own property list files and much more.
Lingon and LaunchControl are inexpensive, and worth every penny even if you only use them infrequently.