Tengo un script de lanzamiento donde el comando que estoy tratando de ejecutar tiene un error (aparentemente eso no es una palabra, lo es ahora), quejándose de un uso inadecuado.
El error específico que recibo es el texto de uso del comando descargado en el registro del sistema. De esto, infiero que la otra información (ruta al comando, tiempo, etc.) en el plist se analiza 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 manual le informa sobre ProgramArguments: "... Tenga en cuenta: muchas personas están confundidas con esta clave. ¡Lea execvp (3) con mucho cuidado! ..."
Bueno, leí execvp (3) y no soy más sabio, así que les pido mucho.
Normalmente, ejecutar 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 dividí en la sección Program/ProgramArguments de mi plist 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 que conste, originalmente tenía la ruta para boinccmd \escaped out, pero eso no funciona, lanzó espacios de escape 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 pareció 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 "... ¡Lea con mucho cuidado! ..." :) También descubrí que tenía que dividir los argumentos en sus partes componentes. Cuando tuve todo eso en su lugar, todo funciona a la perfección. Muchísimas 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 de POR QUÉ debería ser esto, vea la explicación de SirPavlova.
~W
La Program
clave especifica el archivo a ejecutar, y la ProgramArguments
clave especifica los argumentos que se pasarán al proceso de ejecución. Estrictamente hablando, puede pasar los argumentos 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 Program
falta 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 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 la terminal como
/Library/Application\ Support/BOINC\ Data/boinccmd localhost --passwd gobbledygook --project http://setiathome.berkeley.edu/ update
(tenga en cuenta el "--host" que falta).
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 empujar <string>HELLO</string>
en la parte superior de la ProgramArguments
matriz, pero probablemente sea más limpio eliminar la Program
clave 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. actúan como shells de inicio de sesión si su primer argumento comienza con -
, & Vim ingresa a varios modos de emulación si su primer argumento es ed
o vi
en lugar de vim
.
Según la página de 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 argumento en el índice 0, puede ayudar...
carpintero
kevin red
<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 queboinccmd
se informa.carpintero
mmmmmm