A Simple Launchd Tutorial

Suppose you’ve written a little script that you want to run every so often. If you’re using a Mac, then launchd is a perfect tool to use.

It is better than crontab because, among other things, if your computer is off when your program is scheduled to run, launchd will run your program as soon as the computer wakes up. Meanwhile crontab will not.

First thing to do is create a script to run. I’m going to write a simple Node.js but you can use whatever you want.

touch ~/demo/main.js

For the sake of this example, all this script is going to do is log the time when it was run.

console.log("Hello", Date.now())

Now we need to create a launchd configuration plist file.

touch ~/Library/LaunchAgents/com.demo.daemon.plist

A plist file is just Apple’s custom XML format for configurations. Paste this code in there. You may need to change /Users/chet/demo to the directory you are using for this example.

This file specifies a few things:

  • The daemon will start whenever the user logs in.
  • It will execute every 20 seconds.
  • It will output to some log files (very useful for debugging).
  • It will set the environment path (useful if your program uses other commands from usr/local/bin).
  • The command will execute in the /Users/chet/demo directory.
  • And the command is /usr/local/bin/node main.js.

There are a bunch of other options you can read about here. A commonly used option is the KeepAlive option which will restart your script whenever it ends or crashes. This is useful if you want your script to always be running.

Now, we just need to get it running. First, open up the Console.app. You may have never used it before, but it’s a native utility app for debugging this sort of stuff. In the system.log section, you can look for com.demo.daemon to see if there are any system errors when you try to start launchd.

Back in your Terminal, run the following command.

launchctl load ~/Library/LaunchAgents/com.demo.daemon.plist

If you see some errors in the Console.app you can stop the daemon with unload and look for errors in the stderr.log file.

launchctl unload ~/Library/LaunchAgents/com.demo.daemon.plist
cat ~/demo/stderr.log

If all went well, you shouldn’t see anything in the Console.app and you should see logs coming in to the ~/demo/stdout.log file every 20 seconds.

Hello 1525844666922
Hello 1525844687004
Hello 1525844707086
Hello 1525844727169
Hello 1525844747245
Hello 1525844767333
Hello 1525844787419
Hello 1525844807505
Hello 1525844827596
Hello 1525844847681

And there you have it! Now go off and write some web scrapers or something.

Happy Hacking,

Chet Corcos