1

I've created the below launch daemon to run a nodejs program on startup (tiddlywiki in this case):

<?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>Debug</key>
        <true/>
        <key>StandardOutPath</key>
        <string>/tmp/tiddlywiki.stdout</string>
        <key>StandardErrorPath</key>
        <string>/tmp/tiddlywiki.stderr</string>
        <key>Label</key>
        <string>com.activescott.tiddlywiki</string>
        <key>OnDemand</key>
        <false/>
        <key>RunAtLoad</key>
        <true/>
        <key>KeepAlive</key>
        <true/>
        <key>inetdCompatibility</key>
        <dict>
            <key>Wait</key>
            <true/>
        </dict>
        <key>EnvironmentVariables</key>
        <dict>
            <key>PATH</key>
            <string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:</string>
        </dict>
        <key>ProgramArguments</key>
        <array>
            <string>/Volumes/minidata/Dropbox/tiddlywiki/node_modules/.bin/tiddlywiki</string>
            <string>/Volumes/minidata/Dropbox/tiddlywiki/wiki</string>
            <string>--listen</string>
            <string>credentials=creds.csv</string>
            <string>writers=scott</string>
            <string>readers=scott</string>
            <string>port=443</string>
            <string>host=0.0.0.0</string>
            <string>tls-key=key.pem</string>
            <string>tls-cert=server.crt</string>
        </array>
    </dict>
</plist>

The file is named com.activescott.tiddlywiki.plist and it is in the /Library/LaunchDaemons/ folder.

If I load it with the command:

sudo launchctl load -Fw /Library/LaunchDaemons/com.activescott.tiddlywiki.plist

I start it with the below command it and wills tart and work fine - it just doesn't restart automatically when the comp reboots:

sudo launchctl start com.activescott.tiddlywiki

Note, it does take about ~20s to fully start (e.g. respond on a port and write to stdout).

I'm on Mac OS X, 10.13.6 w/ BuildVersion 17G13035

Update:

After a reboot I noticed that the output of sudo launchctl list com.activescott.tiddlywiki shows LastExitStatus as 19968. This value will show 0 if I start it with launchctl. Below is the full output:

{
        "StandardOutPath" = "/tmp/tiddlywiki.stdout";
        "LimitLoadToSessionType" = "System";
        "StandardErrorPath" = "/tmp/tiddlywiki.stderr";
        "Label" = "com.activescott.tiddlywiki";
        "TimeOut" = 30;
        "OnDemand" = true;
        "LastExitStatus" = 19968;
        "Program" = "/Volumes/minidata/Dropbox/tiddlywiki/node_modules/.bin/tiddlywiki";
        "ProgramArguments" = (
                "/Volumes/minidata/Dropbox/tiddlywiki/node_modules/.bin/tiddlywiki";
                "/Volumes/minidata/Dropbox/tiddlywiki/wiki";
                "--listen";
                "credentials=creds.csv";
                "writers=scott";
                "readers=scott";
                "port=443";
                "host=0.0.0.0";
                "tls-key=key.pem";
                "tls-cert=server.crt";
        );
};
9
  • Where do you specify the Program key? i.e. what/where is the program you're running? – user14492 Jun 24 '20 at 22:07
  • 1
    Also have you tried to run this with a script rather than having multiple program arguments. There's also on mount setting, make sure you check if the path to volume exists. Also try with the following keep alive setting: <key>KeepAlive</key> <dict> <key>SuccessfulExit</key> <true/> </dict> This template seems to work so try with this as well: gist.github.com/lordlycastle/0efb8a10d2ccb7a90e4e5b1c9749ccf2 – user14492 Jun 24 '20 at 22:22
  • 1
    Please post the output of grep -F com.activescott.tiddlywiki /var/log/system.log after you reboot. (The last few lines of the output should be sufficient.) – Synoli Jun 25 '20 at 16:13
  • 1
    Try removing the OnDemand and RunAtLoad keys entirely. The man page for launchd.plist advises against both. KeepAlive set to true should be enough to get the daemon rolling. Incidentally, I notice that you are loading the job with -Fw options. The -F option may cause launchctl to ignore the -w option (I'm not sure about that, but it's worth investigating), and if you unload with the -w option you'll automatically disable the job. I wouldn't use those options at all unless you have a reason to. – Ted Wrigley Jun 25 '20 at 16:15
  • @user14492 My understanding is that you can use Program or ProgramArguments. Apple's recent examples use only ProgramArguments and it seems to work when I run it with launchctl load ... – Scott Willeke Jun 29 '20 at 6:21
1

Presuming your application can be run within the Terminal, making an AppleScript program (using Script Editor) containing the commands that you would run in the terminal and then exporting that program as a Run-Only Application, placing it in your /Applications/ directory can create your program launcher.

There is a helpful answer on using do shell script in AppleScript here.

AppleScript Example: Running hdiutil to mount a sparseimage bundle as a Time Machine backup drive

do shell script "hdiutil attach /Volumes/NewVolumeD/TimeMachine.sparsebundle"

Then, navigating to System Preferences > Users & Groups > (your account) > Login Items, unlocking the settings menu and then using the + button on the bottom left to select your launcher application from Applications. That launcher will now run on login, check mark on Hide so that it doesn't throw unwanted messages.

Alternatively, you could make a zsh or bash script and tell AppleScript execute the shell script (given its absolute path) instead of specifying each command in AppleScript itself.

EDIT: Instead of using Login Items, you can place the Application Bundle in /Library/StartupItems (though it is deprecated) if you want it to launch on startup instead of login.

2
  • Thanks for the idea. Definitely not wanting to rely on applescript for starting a non-ui service though. Also I don't even know if applescript can even run on boot (but not on login) – Scott Willeke Jul 1 '20 at 17:58
  • 1
    It's all good! I don't really find a problem with AppleScript and non-UI programs because it still shows stderr output as a dialog, which for my purposes is good enough. But yeah, launchd would still be the way to go for anything more complex. – Kittywhiskers Van Gogh Jul 2 '20 at 15:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .