Scheduling Tasks using launchctl
Tags:
Tags that this post has been filed under.
Recently, I read how to "prevent link riot in my obsidian vault" and I wanted to do something similar. The author wrote a small CLI utility, called wayback-archiver and a script that greps links from markdown files in a directory which then executes the archiver utility to archive the collected links. But how should this be automated in macOS? Crontab comes to mind immediately, but opening the man page shows that it has been deprecated.
DESCRIPTION
[...]
(Darwin note: Although cron(8) and crontab(5) are officially supported
under Darwin, their functionality has been absorbed into launchd(8), which
provides a more flexible way of automatically executing commands. See
launchctl(1) for more information.)
The man page for launchd shows that we should use launchctl
.
The primary and preferred interface to launchd is via the launchctl(1) tool
which (among other options) allows the user or administrator to load and
unload jobs. Where possible, it is preferable for jobs to launch on demand
based on criteria specified in their respective configuration files.
Creating a launch daemon
To configure a job, we need to create a launchd Property List File in ~/Library/LaunchAgents
. For example, ~/Library/LaunchAgents/com.example.archive-links.plist
. In my case, I want to run a script weekly to make sure all links I have in my notes are archived.
<?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>fish.flo.archive-links</string>
<key>ProgramArguments</key>
<array>
<string>archive-links.sh</string>
<string>~/source/obsidian</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Minute</key>
<integer>45</integer>
<key>Hour</key>
<integer>13</integer>
<key>Weekday</key>
<integer>0</integer>
</dict>
</dict>
</plist>
Queuing the job
Now we need to load the script.
launchctl list
shows the currently running agents/daemonslaunchctl load ~/Library/LaunchAgents/fish.flo.archive-links.plist
loads the script → now it is queued to run at the specified time
Links
- https://www.launchd.info/
- https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html#/apple_ref/doc/uid/10000172i-SW7-BCIEDDBJ
- https://benjamincongdon.me/blog/2021/09/19/Preventing-Link-Rot-in-my-Obsidian-Vault/