20 Feb 2025
launchd
is the system-wide service manager for macOS, responsible for starting, stopping, and managing system processes.
It replaces older Unix tools like cron and init, offering better control and more flexibility.
Key Features:
- Handles system and user processes (launchd runs at system level, while launchctl manages per-user jobs)
- Supports scheduled tasks (similar to cron, but can ensure missed jobs run later)
- Can run jobs on specific conditions (e.g., at login, after waking from sleep, on network availability)
- Persistent Jobs (unlike cron, launchd can ensure jobs run after a missed schedule)
Example: Running a Script Every Day at 3 AM
Instead of cron, create a Launch Agent (~/Library/LaunchAgents/com.nic.daily.plist
):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.nic.daily.plist</string>
<key>ProgramArguments</key>
<array>
<string>/path/to/your/script.sh</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>3</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
Ensure that the .plist file is correctly formatted. Run:
plutil -lint ~/Library/LaunchAgents/com.nic.daily.plist
250220-0915 NOT WORKING
Then load the job:
launchctl load ~/Library/LaunchAgents/com.nic.daily.plist
Start the job manually:
launchctl start com.nic.daily.plist
Check status:
launchctl list | grep com.nic.daily.plist
if job running: 12345 0 com.nic.daily.plist
- 12345 is the process ID (PID) of the running job.
- 0 is the exit status of the last run (0 means success).
- com.nic.daily.plist is the label of the job.
if loaded but not running: - 0 com.nic.daily.plist
- - means there is no associated PID because it is not actively running.
- 0 is the last exit status.
if the job is not loaded into launchctl, there will be no output.
If you need to check whether it is available at all (even if not loaded), you can check: launchctl print system/com.nic.daily.plist
To stop the job:
launchctl stop com.nic.daily.plist
To unload the job:
launchctl unload ~/Library/LaunchAgents/com.nic.daily.plist