OS X - How to get simple launchd daemon working on Yosemite and El Capitan

3

I am no stranger to launchd on OS X. I've created several daemons in the past, last with Mountain Lion Mavericks.

However, I seem to be struggling to get the most simplest of plists working on Mavericks and El Capitan. Initially, I copied my plist that runs Tomcat and modified it to get WebSphere Liberty Profile running at startup. After seeing some errors, I decided to try the following example plist from Apple's own [site][1]. The following doesn't even run:

<?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.example.hello</string>

    <key>ProgramArguments</key>
    <array>
        <string>hello</string>
        <string>world</string>
    </array>

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

</dict>

Whenever I place the plist file in /Library/LaunchDaemons and then load the plist, I see the following errors in Console:

10/5/15 11:52:44.868 AM com.apple.xpc.launchd[1]: (com.example.hello) This service is defined to be constantly running and is inherently inefficient.

10/5/15 11:52:44.869 AM com.apple.xpc.launchd[1]: (com.example.hello[66956]) Service could not initialize: 15A284: xpcproxy + 12644 [1472][19011403-4854-3CCD-9FCF-49C36302EB40]: 0x2

10/5/15 11:52:44.870 AM com.apple.xpc.launchd[1]: (com.example.hello) Service only ran for 0 seconds. Pushing respawn out by 10 seconds.

And that's it as far as output. I've tried writing to a StandardOutput and StandardError log, but the log files are empty.

Being as I'm seeing this situation occur on both Yosemite and El Capitan, I thought that it must be something with permissions:

-rw-r--r-- 1 root wheel 418 Oct 5 11:52 helloworld.plist

However, I've tried running the daemon with permissions set to 644 and 755, but I still see the same Console error.

Am I overlooking something?

Chris Harris

Posted 2015-10-05T17:12:01.280

Reputation: 151

Nothing significant has changed. I suggest you close this Question and create a new one on your real problem. Include the WebSphere launchd plist in question, and the exact errors that concerned you. The example doesn't work as-is because it requires that you have a command called hello in the system's default $PATH, and that hello take an argument world. Running this plist as-is on a stock El Capitan system will immediately fail because the system can't find a command hello. – Spiff – 2015-10-05T22:09:21.030

@Spiff - my real problem is getting a plist to work. If I can get a simple example working, then that's all that I need. I already have a working plist that launches a launchd wrapper shell script, which launches Tomcat. However, that plist uses deprecated tags and doesn't use newer tags such as KeepAlive (and yes, I know KeepAlive has been around since OS X 10.5) – Chris Harris – 2015-10-07T15:22:35.643

Answers

1

I was able to create a working example based on the help from @Dooley_labs and @Spiff (thank you).

The following example will echo Hello World to the specified log file every 10 seconds. Console doesn't show any output, but when I view the log file's contents, I see Hello World repeatedly being written to it.

<?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.example.hello</string>

        <key>ProgramArguments</key>
        <array>
            <string>echo</string>
            <string>Hello World</string>
        </array>

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

        <key>StandardOutPath</key>
        <string>/var/log/helloworld.log</string>

    </dict>

</plist>

Chris Harris

Posted 2015-10-05T17:12:01.280

Reputation: 151

can you explain how you did it? where is this plist placed? how do you load it? have you removed the SIP or stuff like that? i'm not able to get this running. PS: there's no evidence of the 10s running – EsseTi – 2015-10-20T11:02:42.597

1@EsseTi - You put the plist file in /Library/LaunchDaemons/ and then type sudo launchctl load <name_of_plist_file> in terminal. To see the evidence, open the log file at /var/log/helloworld.log. You'll see that the plist file gets written to by the daemon. – Chris Harris – 2015-10-21T04:49:13.833

I see, this works. Still not able to make it working with my own script that in osx 10.10 was working. PS: i use script in ~/Library/LaunchAgent and i also tried to move to /Library/LaunchAgent as root, but no luck. i'll start from this example and see what i can do. – EsseTi – 2015-10-21T08:00:12.280

1

As I see it, <key>KeepAlive</key> is outputting com.apple.xpc.launchd[1]: (com.example.hello) This service is defined to be constantly running and is inherently inefficient. It then tells itself to restart the process in 10 seconds from that <key>.

I'm not 100% sure what com.apple.xpc.launchd[1]: (com.example.hello[66956]) Service could not initialize: 15A284: xpcproxy + 12644 [1472][19011403-4854-3CCD-9FCF-49C36302EB40]: 0x2 is saying because I do not have a log of the event, but it looks like it's protesting the event from that original <key> because it's not executing anything else with it. Maybe try removing the <key> or changing it to something else? possibly:

<key>Label</key>
<string>com.example.hello</string>

<key>ProgramArguments</key>
<array>
    <string>hello</string>
    <string>world</string>
</array>

<key>KeepAlive</key>
<false/>

or

<key>Label</key>
<string>com.example.hello</string>

<key>ProgramArguments</key>
<array>
    <string>hello</string>
    <string>world</string>
</array>

Again, I'm not 100% sure about it, but I suggest trying something like that. The OS protests that the keepAlive node isn't needed, so best of luck.

Dooley_labs

Posted 2015-10-05T17:12:01.280

Reputation: 334

I tried setting KeepAlive to false. There's no errors anymore in Console. That's a good sign. I'm not seeing any output to the Console though (hello world or just world, whichever it's supposed to be). – Chris Harris – 2015-10-05T20:06:54.573

0

You're gonna slap yourself when you read this, but, you didn't tell launchctl what executable to run!

The first answer correctly has "echo" as the first "ProgramArguments", but didn't go so far as to say that was the problem.

I believe you could also have done it with the "Program" key, but I'm not certain you would not have to repeat it in the "ProgramArguments" key, which I believe is the arg[] array passed to the executable.

Another thing to be careful of is to always list the full path to executables. launchd/launchctl is pretty tight, but still, a Bad Guy™ could conceivably put a malicious "echo" executable in the default $PATH somewhere, then wait for launchctl to re-parse the LaunchDaemon plist.

Jan Steinman

Posted 2015-10-05T17:12:01.280

Reputation: 131