Obtenir launchd pour lire correctement les arguments du programme


18

J'ai un script launchd où la commande que j'essaie d'exécuter est en erreur (apparemment ce n'est pas un mot, c'est maintenant), se plaignant d'une mauvaise utilisation.

L'erreur spécifique que j'obtiens est le texte d'utilisation de la commande vidé dans le journal système. J'en déduis que les autres informations (chemin d'accès à la commande, timing, etc.) dans le plist sont analysées correctement, mais pas les options de la commande.

Après l'utilisation de la commande, j'ai une dernière ligne:

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

Mais cela signifie simplement "je suis sorti avec une erreur".

Je sais que launchd sépare la commande de ses options et dans la page de manuel vous parle de ProgramArguments: "... Veuillez noter: beaucoup de gens sont confus par cette clé. Veuillez lire execvp (3) très attentivement! .."

Eh bien, j'ai lu execvp (3) et je ne suis pas plus sage, donc je vous demande beaucoup.

Normalement, en exécutant la commande à partir du terminal, cela ressemblerait à ceci:

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

Cela fonctionne un régal.

Et voici comment je l'ai divisé dans la section Program / ProgramArguments de mon plist 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>

(pour mémoire, j'avais à l'origine le chemin vers boinccmd \ échappé, mais cela ne fonctionne pas, launchd échappe les espaces du chemin pour vous)

J'ai essayé de diviser davantage les arguments:

<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>

Mais cela ne semblait pas fonctionner non plus.

Comme toujours, je suis sûr que je manque quelque chose de si simple.

Merci.


RÉPONDRE:

La première ligne de ProgramArguments doit être le chemin d'accès au programme. C'est ce qui me trébuchait et en fait ce que l'on entendait probablement par le commentaire "... Veuillez lire très attentivement! .." :) J'ai également constaté que je devais diviser les arguments en leurs composants. Quand j'avais tout cela en place, tout cela fait un charme. Merci beaucoup.

<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>

Une dernière modification à dire pour une explication facile à comprendre pourQUOI cela devrait être, voir l'explication de SirPavlova.

~ W


En utilisant launchctl list com.label.plist, je peux voir que launchd récupère les bonnes parties de la commande. Je pensais que c'était peut-être un problème lié au -, mais apparemment pas.
Woodgie

1
Je n'ai pas de réponse à votre problème, mais votre premier exemple avec <string>--host localhost</string>ne fonctionnera certainement pas . N'oubliez pas que lorsque vous écrivez une ligne de commande dans un shell, il n'a aucune idée de ce qui fait partie d'une option et de ce qu'est un argument normal - il se divise simplement en espaces avant de passer les arguments au programme en cours d'exécution. En outre, il peut être utile d'afficher l'erreur exacte boinccmdsignalée.
Kevin Reid

Modifié mon message pour dire ce que je vois. Non pas que ça va vous être utile! En outre, j'obtiens la même erreur si je divise les options sur leur espace blanc. Je suppose que c'est le - qui cause le problème d'une manière ou d'une autre.
Woodgie

1
J'essaierais d'utiliser uniquement Program ou ProgramArguments pas les deux
user151019

Réponses:


19

La Programclé spécifie le fichier à exécuter et la ProgramArgumentsclé spécifie les arguments qui seront transmis au processus d'exécution. À strictement parler, vous pouvez transmettre les arguments de votre choix à un processus, mais la convention est que le premier doit être le nom par lequel le processus a été appelé, donc la plupart des programmes ignorent leur premier argument. Le fichier à exécuter est évidemment une information nécessaire, mais si la Programclé est manquante, launchd prétend qu'il a la même valeur que le premier argument à titre ProgramArguments purement pratique .

Votre premier exemple démarre boinccmd et lui donne des arguments qui seraient équivalents à la commande terminal

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

qui indique à boinccmd que vous l'avez invoqué en tant que "--host localhost" et que vous ne lui avez transmis que deux arguments étranges.

Votre deuxième exemple sépare correctement les arguments, mais comme Eddie Kelley l'a suggéré, il en a besoin d'un inséré à l'avant. Il indique à boinccmd que vous l'avez invoqué en tant que "--host", puis passé six autres arguments. boinccmd peut reconnaître les cinq dernières comme étant deux options, mais n'a aucune idée de ce qu'est l'activité "localhost". Pour autant que boinccmd puisse le dire, il a été appelé depuis le terminal comme

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

(notez le "--host" manquant).

boinccmd est probablement l'un de la grande majorité des programmes qui ne se soucient pas de leur premier argument, vous pouvez donc probablement simplement pousser <string>HELLO</string>en tête du ProgramArgumentstableau, mais il est probablement plus propre de supprimer la Programclé et d'utiliser simplement ceci:

<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>

Cela peut sembler une redondance sans signification, mais certains programmes l'utilisent à bon escient: bash et al. agissent comme des shells de connexion si leur premier argument commence par -, et Vim entre dans différents modes d'émulation si son premier argument est edou à la viplace de vim.


1
Vous avez posté alors que je modifiais mon post principal! Ceci est une excellente explication. Je vous remercie.
Woodgie

1
Heureux de vous aider :)
SirPavlova

@SirPavlova, grande aide! Cependant, existe-t-il un outil qui aide la personne à convertir l'invocation de la console au format plist?
gaussblurinc

6

Sur la base de la page de manuel pour exec (3), il semble que le premier argument du programme devrait être le chemin vers l'exécutable:

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 vous pouvez spécifier le chemin d'accès à l'exécutable comme argument à l'index 0, cela peut aider ...


Comme j'ai édité le message pour le montrer, le boinccmd est trouvé et exécuté, les options qui lui sont passées sont en quelque sorte modifiées. Sauf si je manque ce que tu dis.
Woodgie

1
@Woodgie Oui qui a été trouvé dans le programme - vos ProgramArguments sont incorrects, il a besoin du nom de chemin de l'exécutable
user151019

Oh. OH! Je pense que je vois maintenant. Attends, laisse-moi tester ça.
Woodgie

BINGO, faire cela et mettre chaque partie de chaque commande dans son propre conteneur <string> </string> a fonctionné. Je vous remercie. Je t'ai dit que c'etait simple!
Woodgie
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.