All I want to do is. . .
. . .schedule jobs in MacOSX (a guide to launchd).
As of MacOSX 10.4, cron became deprecated in favor of launchd. The biggest advantage of launchd is that it does not assume that your computer is always on (as cron does). Therefore, if your Mac is asleep when a scheduled job was supposed to run, it will automatically run when your Mac is awake.
Contributors: sloria Updated: 10/04/17
Optional (but recommended): Install Lunchy
Lunchy makes it easier to manage your agents.
# Install lunchy $ gem install lunchy
Create a plist
Instead of using crontab's text files, launchd jobs (or "agents") are stored in XML files with a
Your plist files should go in
~/Library/LaunchAgents/ so that they will be loaded automatically when you log in.
Let's say we want to run a python script called
email.py at a regular interval. The script takes one argument, an email address.
Make a file using reverse domain syntax, like
# Make a plist file $ touch ~/Library/LaunchAgents/org.yourusername.email-mom.plist # Open this file in your text editor
Your plist might look like this:
<?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> <!-- The label should be the same as the filename without the extension --> <string>org.yourusername.email-mom</string> <!-- Specify how to run your program here --> <key>ProgramArguments</key> <array> <string>/usr/local/bin/python</string> <string>/Users/yourusername/bin/email.py</string> <string>email@example.com</string> </array> <!-- Run every hour --> <key>StartInterval</key> <integer>3600</integer><!-- seconds --> </dict> </plist>
You can use this as a template.
If you want to schedule the job for calendar intervals (like in cron), you can use
StartCalendarInterval instead of
<!-- StartCalendarInterval examples --> <!-- Run every Sunday (weekday 0) at 15:30/3:30PM --> <key>StartCalendarInterval</key> <dict> <key>Weekday</key> <integer>0</integer> <key>Hour</key> <integer>15</integer> <key>Minute</key> <integer>30</integer> </dict> <!-- You can use an array of dicts to specify multiple intervals --> <!-- Run at the beginning and middle of every hour, every day --> <key>StartCalendarInterval</key> <array> <dict> <key>Minute</key> <integer>0</integer> </dict> <dict> <key>Minute</key> <integer>30</integer> </dict> </array>
Now you need to load your agent and start it.
# Load and start your new agent ## With the built in `launchctl` $ launchctl load ~/Library/LaunchAgents/org.yourusername.email-mom.plist $ launchctl start org.yourusername.email-mom ## Or with Lunchy ## `restart` will unload your agent (if it's loaded), load it, then start the job ## Lunchy sees the argument as a pattern, so you don't have to specify the entire agent-name $ lunchy restart email-mom
You can also see a list of loaded agents.
# Show loaded agents $ launchctl list # OR $ lunchy list
To stop an agent:
# Stop an agent $ launchctl stop org.yourusername.email-mom # OR $ lunchy stop email-mom