Scheduling a shell script with launchd

Author: Jared Beck
Keywords: launchd, schedule, script, task, osx, cron

Overview:
  1. touch ~/Library/LaunchAgents/com.example.mytask.plist
  2. write your scheduled task configuration in the plist file
  3. launchctl load ~/Library/LaunchAgents/com.example.mytask.plist
  4. launchctl start com.example.mytask
Example:

This example shows a bash script that will run every 12 hours.


Thoughts: Expecting to set up a simple cron job today, I learned that Apple deprecated cron in OS 10.4, so I decided to learn launchd. I was disappointed by how long it took to create a simple task, but I was impressed by the rich feature set. While researching this simple use case, I found examples ranging from "run this script every time July 11th falls on a Sunday" to "run rsync when I plug in a usb thumbdrive"!

I am sure there are some good user interfaces out there to simplify common use cases. Then again, if you have the patience for it, it can be good to learn the fundamentals first.

Warning:
Agents in ~/Library/LaunchAgents will only run while you are logged in! Furthermore, StartInterval counts runtime, ie. time the computer is awake. If your computer goes to sleep, then StartInterval is not for you! If you want a scheduled task that runs when no one is logged in, you should check out /Library/LaunchDaemons instead. Plists in that directory should be owned by root:wheel, with rw-r--r-- permissions, and should be launchctl loaded/unloaded with sudo. For my backup, I ended up using StartCalendarInterval instead of StartInterval, and I'm waking up a few minutes before by using the Schedule feature in the Energy Saver control panel.
Tips:
  1. Add debugging to your script by piping echo to logger
  2. Bash expects unix line endings
  3. ~/Library/LaunchAgents is for per-user tasks. There are other directories which may be more appropriate for your project. See man launchd.
Further reading:
  1. man launchd.plist
  2. man launchd
  3. Introduction to System Startup Programming Topics