Scheduling Tasks With launchd

macOS a robust tool for scheduling automated tasks: launchd. While quite different for those used to cron, it’s a pretty great tool for scheduling jobs.

The backstory is that I use the command-line task manager TaskWarrior for managing my todo items and I recently setup a sync server to share data between my personal and work computers. However, TaskWarrior requires manually syncing data by running task sync. This is annoying, so I thought, why not run this automatically?

That’s where launchd comes in! I created a simple config that will run at 8:30 and 5:30 each day, in addition to running on a 10 minute interval throughout the day.

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" ""><plist version="1.0">  <dict>    <key>Label</key>    <string>dev.mskelton.task-sync</string>    <key>ProgramArguments</key>    <array>      <string>/opt/homebrew/bin/task</string>      <string>sync</string>    </array>    <key>StartInterval</key>    <integer>600</integer>    <key>StartCalendarInterval</key>    <array>      <dict>        <key>Hour</key>        <integer>8</integer>        <key>Minute</key>        <integer>30</integer>      </dict>      <dict>        <key>Hour</key>        <integer>17</integer>        <key>Minute</key>        <integer>30</integer>      </dict>    </array>  </dict></plist>

Drop this file in ~/Library/LaunchAgents/ and running the following command to start the schedule.

launchctl bootstrap "gui/$(id -u)" ~/Library/LaunchAgents/dev.mskelton.task-sync.plist

If you make edits to the config, run the following to reload the config.

path=~/Library/LaunchAgents/dev.mskelton.task-sync.plistlaunchctl bootout "gui/$(id -u)" $pathlaunchctl bootstrap "gui/$(id -u)" $path

Now sit back and enjoy the beauty of macOS doing work for you! I was very pleasantly surprised with how well this worked, haven’t had to manually sync my tasks at all since adding this.