Ottenere launchd per leggere correttamente gli argomenti del programma

14

Ho uno script launchd in cui il comando che sto cercando di eseguire è un errore (a quanto pare non è una parola, è ora), lamentando un uso improprio.

L'errore specifico che sto ottenendo è il testo di utilizzo del comando scaricato nel registro di sistema. Da ciò deduco che le altre informazioni (percorso del comando, tempistica ecc.) Nel plist vengono analizzate correttamente, ma non le opzioni del comando.

Dopo l'utilizzo del comando ho un'ultima riga:

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

Ma questo significa semplicemente "Sono uscito con un errore".

So che launchd divide il comando dalle sue opzioni e nella pagina man ti dice di ProgramArguments: "... Nota: molte persone sono confuse da questa chiave. Leggere con precisione execvp (3)! .."

Bene, ho letto execvp (3) e non ne sono più saggio, quindi ti sto chiedendo molto.

Normalmente, eseguendo il comando dal terminale, sarebbe simile a questo:

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

Funziona bene.

Ed è così che l'ho diviso nella sezione Program / ProgramArguments del mio 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>

(per la cronaca, originariamente avevo il percorso per boinccmd \ escapato, ma non funziona, launchd fugge gli spazi nel percorso per te)

Ho provato a suddividere ulteriormente gli argomenti:

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

Ma non sembrava funzionare neanche.

Come sempre, sono sicuro che mi manca qualcosa di così semplice.

Grazie.

Risposta:

La prima riga di ProgramArguments deve essere il percorso del programma. Questo è ciò che mi ha fatto inciampare e, in effetti, ciò che probabilmente intendevo per "... Per favore, leggi attentamente! .." commenta :) Ho anche scoperto che dovevo suddividere gli argomenti nelle loro parti componenti. Quando ho avuto tutto questo, tutto ha un fascino. Grazie mille.

<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 modifica finale da dire per una spiegazione facile da capire sul perché questo dovrebbe essere, vedi la spiegazione di SirPavlova.

~ W

    
posta Woodgie 15.11.2013 - 09:32
fonte

2 risposte

15

Il tasto Program specifica il file da eseguire, & la chiave ProgramArguments specifica gli argomenti che verranno passati al processo in esecuzione. A rigor di termini è possibile passare qualsiasi argomento che si desidera ad un processo, ma la convenzione è che il primo dovrebbe essere il nome con cui è stato richiamato il processo, quindi molti programmi ignorano il loro primo argomento. Il file l'esecuzione è ovviamente un'informazione necessaria, ma se manca la chiave Program , launchd finge di avere lo stesso valore del primo argomento in ProgramArguments puramente come comodità .

Il tuo primo esempio inizia boinccmd & fornisce argomenti che sarebbero equivalenti al comando del terminale

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

che dice a boinccmd che lo hai invocato come "--host localhost" & ha passato solo due argomenti strani.

Il tuo secondo esempio separa correttamente gli argomenti, ma come suggerisce Eddie Kelley, è necessario che ne venga inserito uno in primo piano. Indica a boinccmd che l'hai invocato come "--host", quindi ha passato altri sei argomenti. boinccmd può riconoscere le ultime cinque come due opzioni, ma non ha idea di cosa sia il business "localhost". Per quanto può sapere boinccmd, è stato richiamato dal terminale come

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

(notare il mancante "--host").

boinccmd è probabilmente uno della maggior parte dei programmi a cui non importa quale sia il loro primo argomento, quindi probabilmente potresti spingere solo <string>HELLO</string> all'inizio dell'array ProgramArguments , ma è probabilmente più pulito da rimuovere il tasto Program del tutto & basta usare questo:

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

Può sembrare una ridondanza senza senso, ma alcuni programmi lo usano con buoni risultati: bash et al. agisci come shell di login se il loro primo argomento inizia con - , & Vim immette varie modalità di emulazione se il suo primo argomento è ed o vi anziché vim .

    
risposta data 18.11.2013 - 15:13
fonte
6

In base alla pagina man per exec (3), sembra che il primo argomento del programma dovrebbe essere il percorso dell'eseguibile:

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.

Se puoi specificare il percorso dell'eseguibile come argomento all'indice 0, può essere d'aiuto ...

    
risposta data 15.11.2013 - 23:51
fonte

Leggi altre domande sui tag