I used Apple's seemingly straightforward docs to create a LaunchDaemon to run a Node.js script I wrote.
Here's the plist
file. It's basically exactly a copy-paste from Apple's docs, set to run every 300 seconds:
<?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>com.wintr.eodemail</string>
<key>ProgramArguments</key>
<array>
<string>~/projects/eod_email/eod</string>
</array>
<key>StartInterval</key>
<integer>300</integer>
<key>StandardOutPath</key>
<string>/var/log/eod-email.log</string>
<key>StandardErrorPath</key>
<string>/var/log/eod-email.log</string>
<key>Debug</key>
<true/>
</dict>
</plist>
Here's the error I get in /var/log/system.log
:
Jul 22 10:55:52 Nick-Cox com.apple.xpc.launchd[1] (com.wintr.eodemail[7097]): Service could not initialize: 14E46: xpcproxy + 13421 [1402][7D917364-B96E-3F93-B923-A89B5BF5736D]: 0x2
What I've done:
- It has the same permissions as the rest of the files in /Library/LaunchDaemons (
-rw-r--r--
, owned by root) - I read the docs for xpc, but that didn't help much.
- I made sure that the Node.js script was adequately permissive (777), and runnable from the command line (it is).
- Tried the absolute path to the file (
/Users/nickcox/projects/eod_email/eod
) and made sure I ranlaunchctl unload (daemonname)
andlaunchctl load (daemon name)
This seems much more complicated than cron, which is apparently deprecated, according to those Apple docs. What do I need to do to get this script to run on a schedule?
Best Answer
Getting started with launchctl can definitely be a frustrating experience. I found a lot of articles explaining what you should do but few little downloadable samples. Here is a simple LaunchDaemon that will hopefully be a good starting point. You can just download the files here if you don't feel like copying and pasting.
Note: you need to replace MY_USER_NAME with your username. The plist needs to find your script.
This is a simple daemon script that will append the datetime to a file on your desktop. Note: since the script is run as root, tilde (~) won't be the home directory you expect.
Finally, I always write a little shell script to install the LaunchDaemons since it's easy to make a mistake. Since launchctl runs your script as root it requires that script's permissions not be writeable by others, since that would essentially give them root privileges.