Setting up Launchd for Offlineimap
With cron being depreciated in OSX a few versions ago, the proper way to run a script at set intervals is with Launchd. Below is just a quick setup for getting Offlineimap to run every 2 minutes to refresh your local email folders.
Update Dec 7, 2016: I've recently moved to using Homebrew Services which provides all of the Offlineimap/Launchd goodness out of the box when you install Offlineimap with Homebrew. After installing Homebrew Services, run brew services list
to see what installed apps have services support. This post will stay as it is for future reference for anyone wanting to set it up manually.
Launchd Plist
All Launchd agents consist of simple XML files in the plist format by Apple. These contain all the information for what to run and how often. The best way to edit or create a plist file is with Xcode as it has a really nice editor. Since it is all just XML you could just edit it in your editor of choice and save. In order to have this script start at login, simply add it to ~/Library/LaunchAgents
.
If you want you can create a new file in the ~/Library/LaunchAgents
with the following code and you should be good to go. We'll walk through the parts so you understand what's going on as well.
<!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.grantlucas.offlineimap.plist</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/offlineimap</string>
<string>-u</string>
<string>quiet</string>
</array>
<key>StartInterval</key>
<integer>120</integer>
</dict>
</plist>
Note: These scripts only launch when you log in so if you just save a file there, it will not run until you log out and in again. In order for this to become active right away run launchctl load ~/Library/LaunchAgents/com.grantlucas.offlineimap.plist
. After this point it should load automatically when you log in.
Plist Explanation
Header
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
This just states the format of the XML file and is auto generated by Xcode. If you're creating yours manually, be sure that this is at the beginning.
Label
<string>com.grantlucas.offlineimap.plist</string>
This is a required value which tells Launchd the name of the script running. This works in a reverse format to a normal domain. Since I own grantlucas.com, I can put com.grantlucas.offlineimap as the name with plist as the file extension. You can change this to what ever you want. If you don't have your own domain just use something like com.local etc
. Just ensure that it won't conflict with any other script. This value should be the same as the file name of this plist.
Program Arguments
<array>
<string>/usr/local/bin/offlineimap</string>
<string>-u</string>
<string>quiet</string>
</array>
Program arguments controls what is actually run when this is invoked and consists of an array of strings. Normally you would invoke Offlineimap with just offlineimap
but here, since it doesn't know about your PATH, we need to give it the absolute path. Yours may exist elsewhere so run which offlineimap
to get the appropriate value.
The next two strings are just setting the user interface of Offlineimap to quite so that nothing is output.
Start Interval
<integer>120</integer>
Start interval is just how often the program arguments should be run in seconds. Here we have it set to 120 so that Offlineimap runs every 2 minutes.
Conclusion
Overall this script is pretty simple and does what it needs to do. I'm sure Cron could still be used in OSX but Launchd is the "proper" way to do it now.
If you have any questions or issues implementing this, hit my up at Twitter (grantlucas) or email me through this site's contact form.