Iniciando para leer los argumentos del programa correctamente


18

Tengo un script de launchd donde el comando que estoy tratando de ejecutar es un error (aparentemente eso no es una palabra, ahora lo es), quejándose de un uso incorrecto.

El error específico que obtengo es el texto de uso del comando volcado al registro del sistema. De esto deduzco que la otra información (ruta al comando, sincronización, 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 del manual le informa sobre los argumentos del programa: "... Tenga en cuenta: esta clave confunde a muchas personas. ¡Lea execvp (3) con mucho cuidado! .."

Bueno, leí execvp (3) y no soy el más sabio, así que te pregunto mucho.

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

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

Esto funciona de maravilla.

Y así es como lo he dividido en la sección Programa / Argumentos de programa de mi pliego 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 tenía la ruta a boinccmd \ escapado, pero eso no funciona, launchd escapa espacios en la ruta para usted)

He intentado dividir los argumentos aún más:

<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 parecía funcionar.

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

Gracias.


RESPONDER:

La primera línea de argumentos del programa debe ser el camino hacia el programa. Esto es lo que me estaba haciendo tropezar y, de hecho, lo que probablemente significaba el comentario "... ¡Lee con mucho cuidado! .." :) También descubrí que tenía que dividir los argumentos en sus 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 edición final para decir una explicación fácil de entender sobre POR QUÉ esto debería ser, vea la explicación de SirPavlova.

~ W


Usando launchctl list com.label.plist puedo ver que launchd está obteniendo las partes correctas del comando para juntarlas. Estaba pensando que tal vez era un problema relacionado con el -, pero aparentemente no.
Woodgie

1
No tengo una respuesta para su problema, pero su primer ejemplo con <string>--host localhost</string>definitivamente no funcionará. Recuerde, cuando escribe una línea de comando en un shell, no tiene idea de qué es parte de una opción y qué es un argumento regular: simplemente se divide en espacios antes de pasar los argumentos al programa que se está ejecutando. Además, podría ayudar si mostrara el error exacto que boinccmdinforma.
Kevin Reid

Edité mi publicación para decir lo que estoy viendo. ¡No es que sea de alguna ayuda! Además, obtengo el mismo error si divido las opciones en su espacio en blanco. Supongo que es lo que está causando el problema de alguna manera.
Woodgie

1
Intentaría usar solo Program o ProgramArguments, no ambos
user151019

Respuestas:


19

La Programclave especifica el archivo a ejecutar, y la ProgramArgumentsclave especifica los argumentos que se pasarán al proceso de ejecución. Hablando estrictamente, puede pasar cualquier argumento que desee 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 a ejecutar es obviamente información necesaria, pero si Programfalta la clave, launchd finge que tiene el mismo valor que el primer argumento, ProgramArguments simplemente por conveniencia .

Su primer ejemplo comienza boinccmd y le da argumentos que serían equivalentes al comando de terminal

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

que le dice a boinccmd que lo invocaste como "--host localhost" y solo le pasaste dos argumentos extraños.

Su segundo ejemplo separa los argumentos correctamente, pero como sugirió Eddie Kelley, necesita uno insertado al 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". Hasta donde puede ver boinccmd, fue invocado desde la terminal como

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

(tenga en cuenta la falta "--host").

boinccmd es probablemente uno de la gran mayoría de los programas a los que no les importa cuál es su primer argumento, por lo que probablemente podría simplemente empujar <string>HELLO</string>a la cabeza de la ProgramArgumentsmatriz, pero probablemente sea más limpio eliminar la Programclave por completo y simplemente usar 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 -, y Vim ingresa a varios modos de emulación si su primer argumento es edo en vilugar de vim.


1
¡Publicaste cuando estaba editando mi publicación principal! Esta es una gran explicación. Gracias.
Woodgie

1
Me alegro de ser de ayuda :)
SirPavlova

@SirPavlova, ¡gran ayuda! Sin embargo, ¿hay alguna herramienta que ayude a la persona a convertir la invocación de la consola a formato plist?
gaussblurinc

6

Basado en la página man para 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 argumento en el índice 0, puede ayudar ...


Como he editado la publicación para mostrarla, se está encontrando y ejecutando boinccmd, las opciones que se le están pasando de alguna manera están siendo destrozadas. A menos que me pierda lo que dices.
Woodgie

1
@Woodgie Sí, que se encontró en el Programa: sus argumentos del programa son incorrectos, necesita el nombre de la ruta del ejecutable
usuario151019

Oh. ¡OH! Creo que veo ahora. Espera, déjame probar eso.
Woodgie

BINGO, hacer eso y poner cada parte de cada comando en su propio contenedor <string> </string> funcionó. Gracias. ¡Te dije que era sencillo!
Woodgie
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.