Have a command-line app run at startup (and relaunch if it crashes)
12-31-2015, 05:30 PM,
Post: #1
Have a command-line app run at startup (and relaunch if it crashes)
All right, so it appears I'm almost totally hopeless when there's not a GUI around. I managed to get homebridge installed and running on my Mac to control my WeMo devices (non-HomeKit compatible) with Siri (my shiny new 4th-gen Apple TV serves to make the devices controllable with Siri when I'm outside of my wi-fi network). It took a bit of doing, but when it's working, it's quite neat; for one, I don't have to track down my WeMo app and tap away to get the lights on, nor do I have to hope IFTTT manages to correctly send the power toggle signal when I send it a text. Key takeaway is, when it's working. I find homebridge often crashes and needs to be restarted from the Terminal. Very hard to do if one is not in front of the Mac, for example.

I've been trying to follow some instructions online for creating a LaunchAgent to get it running, but I don't seem to be having much luck with it. Like I said, no GUI, and I'm in trouble. What I've managed to do is create an AppleScript that opens Terminal, runs the 'homebridge' command, then hides the window. It's ugly, in that it leaves the Terminal window in the dock, but it somewhat accomplishes the task.

What I'd like to do is have this run at startup without having to keep the Terminal app in my dock, and, if possible, have it know to restart if it crashes. Nothing worse than trying to show someone how cool something is, only to have it not work. There's a symlink at /usr/local/bin/homebridge which redirects to /usr/local/lib/node_modules/homebridge/bin/homebridge.

So, I guess the question is, is what I want to do even possible? The eventual goal would be to have this running on a dedicated device like a Raspberry Pi, but that's not in the cards yet.
12-31-2015, 11:06 PM,
Post: #2
RE: Have a command-line app run at startup (and relaunch if it crashes)
Sounds like you want to create a daemon. It's documented here:

https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html

I have a cron job that runs every minute that I've been meaning to convert to this, but I haven't had the patience for it. So I've never done it personally, but I think this is what you want to do.
bedstuy Wrote:mocking a pair of $500 jeans is a form of class warfare... why do you hate my social status?
01-01-2016, 02:20 AM,
Post: #3
RE: Have a command-line app run at startup (and relaunch if it crashes)
Yeah, you want launchd
The chaos army seems suspiciously well organized.
flickr | Stupid Blog | Twitter
01-02-2016, 03:18 AM,
Post: #4
RE: Have a command-line app run at startup (and relaunch if it crashes)
(12-31-2015, 11:06 PM)roo Wrote: Sounds like you want to create a daemon.   It's documented here:

https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html

I have a cron job that runs every minute that I've been meaning to convert to this, but I haven't had the patience for it.  So I've never done it personally, but I think this is what you want to do.
Neat, that takes a lot of the hackery out of my rc.common file.
01-02-2016, 09:13 AM,
Post: #5
RE: Have a command-line app run at startup (and relaunch if it crashes)
If you want examples you can look at some projects in the homebrew library that install as services. There's some pretty good prior art in there. Some pretty bad, too, but hey...
The chaos army seems suspiciously well organized.
flickr | Stupid Blog | Twitter
01-02-2016, 09:22 AM, (This post was last modified: 01-02-2016, 09:23 AM by Skippy.)
Post: #6
RE: Have a command-line app run at startup (and relaunch if it crashes)
All right, I think I've got it going now. I've been following along the instructions on GitHub and kept running into this message in Console:

Code:
1/1/2016 5:57:07.604 PM com.apple.xpc.launchd[1]: (org.node.homebridge) Service only ran for 0 seconds. Pushing respawn out by 10 seconds.
1/1/2016 5:57:17.614 PM com.apple.xpc.launchd[1]: (org.node.homebridge[11126]) Service could not initialize: 15C50: xpcproxy + 12644 [1472][13E77DA5-3602-31BF-B074-49D4EE27E9D8]: 0xd

So, launching homebridge fails. But what I hadn't taken into account is the millions of times I've already tried this, as both a LaunchAgent and a LaunchDaemon. One of the folks on GitHub posted the plist he used, which included logging to a folder in ~/Library/Logs called Homebridge. I used his example, and tried it in both /Library/LaunchDaemons and /Library/LaunchAgents, and finally in ~/Library/LaunchAgents. I'm not sure if it was placing the plist in one of those first two locations, or that someone suggested changing the ownership of the plist file to root, but ~/Library/Logs/Homebridge was now also owned by root, which meant that my plist in ~/Library/LaunchAgents couldn't write logs to ~/Library/Logs/Homebridge, causing the LaunchAgent to fail. I deleted the folder and had launchctl relaunch my LaunchAgent (in ~/Library/LaunchAgents, and ownership under my user), which recreated ~/Library/Logs/Homebridge and runs properly.

Of course, now homebridge doesn't seem to be available when my iPhone isn't connected to the home wi-fi, but I'm guessing my Apple TV is asleep and hasn't synced the HomeKit config up to the cloud. Fingers crossed, waking the Apple TV will do it.

Thanks for pointing me in the right direction!
There is no dark side of the moon, really…matter of fact, it's all dark.
01-02-2016, 10:19 AM,
Post: #7
RE: Have a command-line app run at startup (and relaunch if it crashes)
~/Library/LaunchAgents is for scripts that run "on demand" and that can be put to sleep or outright dropped. Launchd will respawn them when they're requested. The only downside to this is that if your script takes time to start up, yeah, even hundreds of milliseconds can be an issue here, then whatever was looking for it could give up and give the appearance that your service isn't running where in fact it was just getting started.

/Library/LaunchDaemons is where you put scripts that launch on system boot. These you either need to reboot or manually load in to Launchd to get started the first time. Something like:

Code:
sudo launchctl load -wF /Library/LaunchDaemons/myService.plist
The chaos army seems suspiciously well organized.
flickr | Stupid Blog | Twitter
01-02-2016, 04:39 PM,
Post: #8
RE: Have a command-line app run at startup (and relaunch if it crashes)
Awesome.

I can now say the issues I was having were probably related to giving ownership of the plist to root, which then set the folder for the log files up as owned by root. I took the working plist from ~/Library/LaunchAgents and unloaded it with launchctl, then moved it to /Library/LaunchDaemons as Gippy suggested, and had launchctl reload it. Worked like a charm. I'm now giddily flicking on my front porch light with Siri.

Also resolved the HomeKit stuff, too. Signed out of iCloud on my Apple TV and iPhone, and signed back in. That, and I may have resolved some lingering network issues too. Considering the networking setup in my home looks like an IT guy threw up, everything seemingly working perfectly (touch wood) is a pleasant surprise.
There is no dark side of the moon, really…matter of fact, it's all dark.
01-03-2016, 11:26 AM,
Post: #9
RE: Have a command-line app run at startup (and relaunch if it crashes)
Permissions are a bitch.
The chaos army seems suspiciously well organized.
flickr | Stupid Blog | Twitter
01-03-2016, 11:58 AM,
Post: #10
RE: Have a command-line app run at startup (and relaunch if it crashes)
so is launchd!
bedstuy Wrote:mocking a pair of $500 jeans is a form of class warfare... why do you hate my social status?
01-03-2016, 03:28 PM,
Post: #11
RE: Have a command-line app run at startup (and relaunch if it crashes)
True, dat.
The chaos army seems suspiciously well organized.
flickr | Stupid Blog | Twitter


Forum Jump: