6

Can somebody please clarify how launchd's Program and ProgramArguments configuration parameters should be used? I tried to register a service which on the command line I'd start like this:

$ /foo/bar/baz/python /foo/bar/baz/service start

I have tried divvying that up in various ways for launchd:

<key>Program</key>
<string>/foo/bar/baz/python</string>
<key>ProgramArguments</key>
<array>
    <string>/foo/bar/baz/service</string>
    <string>start</string>
</array>

or

<key>Program</key>
<string>/foo/bar/baz/python</string>
<key>ProgramArguments</key>
<array>
    <string>/foo/bar/baz/service start</string>
</array>

or

<key>ProgramArguments</key>
<array>
    <string>/foo/bar/baz/python</string>
    <string>/foo/bar/baz/service</string>
    <string>start</string>
</array>

or

<key>Program</key>
<string>/bin/bash</string>
<key>ProgramArguments</key>
<array>
    <string>-c</string>
    <string>/foo/bar/baz/python /foo/bar/baz/service start</string>
</array>

and just about any other variation that would seem to make sense. The service always failed with various different errors though. The only thing that worked was to create a .sh script with the exact line and run that via launchd.

So, to understand launchd services once and for all: How does launchd use these two configuration parameters, how would I replicate my bash command with them and what is the difference between both?
Or am I perhaps just stumbling across a problem of running this particular service with and without some environment variables which exist when executing it via bash? The service itself did not provide any useful output.

I have consulted the execvp(3) manual entry as advised in launchd.plist(5), but it did not really further my understanding.

deceze
  • 473
  • 1
  • 6
  • 20

1 Answers1

4

If Program is specified, it will always be the program executed, even if ProgramArguments has been specified as well.

<key>Program</key>
<string>/foo/bar/baz/python</string>
<key>ProgramArguments</key>
<array>
    <string>/foo/bar/baz/python</string>
    <string>/foo/bar/baz/service</string>
    <string>start</string>
</array>

In this case the first element in ProgramArguments is not actually evaluated, but it is passed as argv[0] to the program being executed. Usually this is not needed, but it has its uses. For instance the program may inspect argv[0] and run in a different mode depending on this value.

For everything else it is sufficient to only use ProgramArguments. This job definition works exactly as the one above:

<key>ProgramArguments</key>
<array>
    <string>/foo/bar/baz/python</string>
    <string>/foo/bar/baz/service</string>
    <string>start</string>
</array>
LCC
  • 181
  • 1
  • 1