Launchd for Cron Jobs
osxAlthough cron is nominally supported on OS X, the preferred alternative
seems to be launchd.
It is often used to run jobs at startup (much like an init script), but
it also has configuration options to produce cron-like scheduling. For
more information, check out the launchd(8)
and
launchd.plist(5)
man page, and pay particular attention to
the StartCalendarInterval
attribute.
This is a plist file I’m using to get launchd to periodically run a script which pulls down copies of database dumps from remote servers and then uploads them to S3:
<?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.urgetopunt.backup</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/ruby</string>
<string>/Users/jparker/bin/backup.rb</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>0</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
</dict>
</plist>
The file lives in
$HOME/Library/LaunchAgents/com.urgetopunt.backup.plist
,
and it was loaded into launchd by running the following command (no root
privileges necessary):
$ launchctl load -w $HOME/Library/LaunchAgents/com.urgetopunt.backup.plist
Crontabs are still, in my opinion, much easier to deal with than XML documents, but launchd does offer certain advantages for desktop platforms. If my Mac is asleep when a cron job is scheduled to run, that run is missed. If launchd determines that a run was missed because the system was asleep, it runs the job when the system wakes up. If multiple consecutive runs are missed, it only runs the job once to get caught up.