How to start a service using Mac OSX's launchctl

36,962

Solution 1

Update June 2020

I created a cross-platform tool to handle creating launchd and systemd service files:

Using launchd

launchd can easily get into "weird" states.

  • load means to read the config file and potentially schedule a launch.
  • unload means to stop and unschedule the config file
  • start will start the service (ignoring the schedule, I believe)
  • stop will stop the service (again, ignoring the schedule)

Generally if you want to "restart" it you unload and reload the config like this:

launchctl unload -w ~/Library/LaunchAgents/com.apple.myservice.plist
launchctl load -w ~/Library/LaunchAgents/com.apple.myservice.plist

The -w means "write" which means that the change will affect reboots (will load every login or boot... or will not load ever again at login or boot).

If it's a system-level service (in /Library/LaunchDaemons or /Library/LaunchAgents you may need to do it with sudo (and if you did it without sudo by mistake, you may need to unload it without sudo and then reload it with sudo)

The key in a file that causes it to start on load is RunAtLoad (and KeepAlive keeps it running if it dies for some reason)

<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>

It's sometimes tricky to get debug logging from launchctl itself, but the keys StandardErrorPath and StandardOutPath can at least help you know if your application is dying due to missing or bad information (an unexpanded environment variable or non-writable path, for example). Just be sure that the path you specify is writable by the user running the process.

<key>StandardErrorPath</key>
<string>/tmp/appname-error.log</string>
<key>StandardOutPath</key>
<string>/tmp/appname-info.log</string>

Because they're so hard to debug, I'd recommend using LaunchControl or launched and mix that with a healthy reading of launchd.info.

Also, there are a number of debugging hints here: https://serverfault.com/questions/183589/how-do-i-activate-launchd-logging-on-os-x

I haven't tried it yet myself, but this solution looks the simplest:

sudo launchctl log level debug 
tail -f /var/log/system.log

Solution 2

I ran into similar problems today.

Simply unload the service and load it again solves the File exists problem.

It looks like every time you update a plist file you're gonna have to do that.

Share:
36,962

Related videos on Youtube

almel
Author by

almel

Bitcoin enthusiast working to promote Bitcoin 2.0. PM me for any work involving help developing bitcoin technologies.

Updated on September 18, 2022

Comments

  • almel
    almel almost 2 years

    Why does my configuration plist file not load as a service using launchctl?

    I am running OSX Yosemite, and I have read this excellent tutorial on using launchctl http://nathangrigg.net/2012/07/schedule-jobs-using-launchd/

    I have created a correct .plist file with the service's configuration (I know this is correct because it's an almost-exact copy of a working plist config file I created several years ago). I type in

    launchctl load ~/Library/LaunchAgents/com.apple.myservice.plist
    

    and get in response

    ~/Library/LaunchAgents/com.apple.myservice.plist: File exists
    

    That's not terribly descriptive, but I go and type

    launchctl start com.apple.myservice
    

    and there's no output and nothing happens. I've also tried to use

    launchctl enable ~/Library/LaunchAgents/com.apple.myservice.plist
    

    and I just get a

    Usage: launchctl enable <service-target>
    

    in response.

    Can someone please reply with the correct syntax for loading a launchd service on OSX Yosemite?

    • Arjan
      Arjan about 9 years
      Maybe load -w will help. "I know this is correct because it's an almost-exact copy of a working plist config file I created several years ago" -- so, you changed the value for Label, I hope? Are you sure it's not some on-demand service? You'll need to show us the plist file. Also, launchctl enable does not expect a path; see things like user/<uid>/[service-name] in man launchctl, or see What is the difference between a service-name and a service-target?.
    • Arjan
      Arjan about 9 years
      Also, make sure the .plist file is NOT writable by group and world. And as an aside, if it's not some Apple provided service, then using com.apple will just be confusing in the future...
    • Arjan
      Arjan about 9 years
      ...and finally: are you sure the File exists is not some output of the process you're trying to run? What does Console say? In the end: we just need to see that plist file.
    • almel
      almel about 9 years
      @Arjan, I forgot to change the label on the .plist file from the previous correct one I used, which explains the "File exists" output. Now that it's changed to the correct label it works as expected. If you wanted to reply to my original question I will accept it as correct.
    • Marek R
      Marek R about 5 years
      you didn't show contents of com.apple.myservice.plist so question is what are the rules for system to start your service? How you defined when it should be started?