Obtención de launchd para leer los argumentos del programa correctamente

13

Tengo una secuencia de comandos launchd en la que el comando que estoy intentando ejecutar es un error (aparentemente no es una palabra, ahora lo es), quejándose de un uso incorrecto.

El error específico que recibo es el texto de uso del comando volcado en el registro del sistema. De esto deduzco que la otra información (ruta al comando, tiempo, etc.) en el plist se está analizando correctamente, pero no las opciones del comando.

Después del uso del comando tengo una última línea:

18/11/2013 09:30:00.101 com.apple.launchd.peruser.501: (fake.lable.seti[33833]) Exited with code: 1

Pero eso solo significa "Salí con un error".

Sé que launchd divide el comando de sus opciones y en la página de comando man le informa sobre Programgguments: "... Tenga en cuenta: esta tecla confunde a muchas personas. Lea atentamente execvp (3)!"

Bueno, leí execvp (3) y no soy consciente de eso, así que te pregunto mucho.

Normalmente, ejecutando el comando desde el terminal se vería así:

/Library/Application\ Support/BOINC\ Data/boinccmd --host localhost --passwd gobbledygook --project http://setiathome.berkeley.edu/ update

Esto funciona muy bien.

Y así es como lo he dividido en la sección Program / ProgramArguments de mi lista de LaunchAgent:

<key>Program</key>
    <string>/Library/Application Support/BOINC Data/boinccmd</string>
<key>ProgramArguments</key>
    <array>
        <string>--host localhost</string>
        <string>--passwd gobbledygook</string>
        <string>--project http://setiathome.berkeley.edu/ update</string>
    </array>

(para el registro, originalmente tuve la ruta a boinccmd \ escape, pero eso no funciona, launchd escapa espacios en la ruta para ti)

He intentado dividir más los argumentos:

<key>Program</key>
    <string>/Library/Application Support/BOINC Data/boinccmd</string>
<key>ProgramArguments</key>
    <array>
        <string>--host</string>
        <string>localhost</string>
        <string>--passwd</string>
        <string>gobbledygook</string>
        <string>--project</string>
        <string>http://setiathome.berkeley.edu/</string>
        <string>update</string>
    </array>

Pero eso tampoco parece funcionar.

Como siempre, estoy muy seguro de que me estoy perdiendo algo tan simple.

Gracias.

RESPUESTA:

La primera línea de ProgramArguments debe ser la ruta al programa. Esto es lo que me estaba haciendo tropezar y, de hecho, lo que probablemente significaba el comentario "... Por favor, lea con mucha atención! .." :) También descubrí que tenía que dividir los argumentos en sus partes componentes. Cuando tuve todo eso en su lugar, todo funciona de maravilla. Muchas gracias.

<key>Program</key>
    <string>/Library/Application Support/BOINC Data/boinccmd</string>
<key>ProgramArguments</key>
    <array>
        <string>/Library/Application Support/BOINC Data/boinccmd</string>
        <string>--host</string>
        <string>localhost</string>
        <string>--passwd</string>
        <string>gobbledygook</string>
        <string>--project</string>
        <string>http://setiathome.berkeley.edu/</string>
        <string>update</string>
    </array>

Una última edición para una explicación fácil de entender sobre POR QUÉ debe ser esto, vea la explicación de SirPavlova.

~ W

    
pregunta Woodgie 15.11.2013 - 09:32

2 respuestas

14

La clave Program especifica el archivo a ejecutar, & La clave ProgramArguments especifica los argumentos que se pasarán al proceso de ejecución. Hablando estrictamente, puede pasar los argumentos que quiera a un proceso, pero la convención es que el primero debe ser el nombre con el que se invocó el proceso, por lo que la mayoría de los programas ignoran su primer argumento. El archivo para ejecutar es obviamente la información necesaria, pero si falta la clave Program , launchd finge que tiene el mismo valor que el primer argumento en ProgramArguments simplemente como una conveniencia .

Tu primer ejemplo comienza boinccmd & le da argumentos que serían equivalentes al comando terminal

--host\ localhost --passwd\ gobbledygook --project\ http://setiathome.berkeley.edu/\ update

que le dice a boinccmd que lo invocaste como "--host localhost" & Solo le pasé dos argumentos extraños.

Su segundo ejemplo separa los argumentos correctamente, pero como Eddie Kelley sugirió que necesita uno insertado en el frente. Le dice a boinccmd que lo invocó como "--host", luego pasó otros seis argumentos. boinccmd puede reconocer las últimas cinco como dos opciones, pero no tiene idea de qué se trata el negocio "localhost". Por lo que boinccmd puede decir, se invocó desde el terminal como

/Library/Application\ Support/BOINC\ Data/boinccmd localhost --passwd gobbledygook --project http://setiathome.berkeley.edu/ update

(note la falta "--host").

boinccmd es probablemente uno de la gran mayoría de los programas a los que no les importa cuál sea su primer argumento, por lo que probablemente en realidad solo hay que empujar <string>HELLO</string> a la cabeza de la matriz ProgramArguments , pero probablemente sea más limpio eliminar la clave Program en total & solo usa esto:

<key>ProgramArguments</key>
    <array>
        <string>/Library/Application Support/BOINC Data/boinccmd</string>
        <string>--host</string>
        <string>localhost</string>
        <string>--passwd</string>
        <string>gobbledygook</string>
        <string>--project</string>
        <string>http://setiathome.berkeley.edu/</string>
        <string>update</string>
    </array>

Puede parecer una redundancia sin sentido, pero algunos programas usan esto con buenos resultados: bash et al. actuar como shells de inicio de sesión si su primer argumento comienza con - , & Vim ingresa en varios modos de emulación si su primer argumento es ed o vi en lugar de vim .

    
respondido por el SirPavlova 18.11.2013 - 15:13
5

Según la página del manual de exec (3), parece que el primer argumento del programa debería ser la ruta al ejecutable:

The execv(), execvp(), and execvP() functions provide an array of pointers to null-terminated strings
 that represent the argument list available to the new program.  The first argument, by convention,
 should point to the file name associated with the file being executed. The array of pointers must be
 terminated by a NULL pointer.

Si puede especificar la ruta al ejecutable como el argumento en el índice 0, puede ayudar ...

    
respondido por el Eddie Kelley 15.11.2013 - 23:51

Lea otras preguntas en las etiquetas