Ottenere launchd per leggere correttamente gli argomenti del programma


18

Ho uno script launchd in cui il comando che sto cercando di eseguire è errato (apparentemente non è una parola, lo è ora), lamentandosi di un uso improprio.

L'errore specifico che sto ricevendo è 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'uso 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 solo "Sono uscito con un errore".

So che launchd divide il comando dalle sue opzioni e nella pagina man ti dice ProgramArguments: "... Nota: molte persone sono confuse da questa chiave. Per favore leggi execvp (3) molto attentamente! .."

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

Normalmente, eseguendo il comando dal terminale sarebbe simile al seguente:

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

Questo funziona a meraviglia.

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 di boinccmd \ scappato, ma che non funziona, launchd sfugge agli 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 neanche quello sembrava funzionare.

Come sempre, sono molto sicuro che mi manchi 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 intendeva con il commento "... Per favore leggi molto attentamente! .." :) Ho anche scoperto che dovevo dividere gli argomenti nelle loro parti componenti. Quando avevo tutto questo a posto, tutto funzionava a meraviglia. 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>

Un'ultima modifica da dire per una spiegazione di facile comprensione del PERCHÉ dovrebbe essere, vedi la spiegazione di SirPavlova.

~ W


Usando l'elenco launchctl com.label.plist posso vedere che launchd sta facendo mettere insieme le parti corrette del comando. Stavo pensando che forse era un problema legato al -, ma apparentemente no.
Woodgie,

1
Non ho una risposta per il tuo problema, ma il tuo primo esempio con <string>--host localhost</string>sicuramente non funzionerà. Ricorda, quando scrivi una riga di comando su una shell, non ha idea di cosa faccia parte di un'opzione e di cosa sia un argomento regolare: si divide solo negli spazi prima di passare gli argomenti al programma in esecuzione. Inoltre, potrebbe essere utile mostrare l'errore esatto che boinccmdviene segnalato.
Kevin Reid,

Ho modificato il mio post per dire quello che sto vedendo. Non che sarà di alcun aiuto! Inoltre, sto ottenendo lo stesso errore se divido le opzioni sul loro spazio bianco. Immagino sia il - che sta causando il problema in qualche modo.
Woodgie,

1
Vorrei provare a utilizzare solo Program o ProgramArguments non entrambi
user151019

Risposte:


19

La Programchiave specifica il file da eseguire e la ProgramArgumentschiave specifica gli argomenti che verranno passati al processo di esecuzione. A rigor di termini puoi passare qualsiasi argomento tu voglia a un processo, ma la convenzione è che il primo dovrebbe essere il nome con cui è stato invocato il processo, quindi la maggior parte dei programmi ignora il loro primo argomento. Il file da eseguire è ovviamente un'informazione necessaria, ma se Programmanca la chiave, launchd finge che abbia lo stesso valore del primo argomento ProgramArguments puramente per comodità .

Il tuo primo esempio avvia boinccmd e gli fornisce argomenti che sarebbero equivalenti al comando terminal

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

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

Il tuo secondo esempio separa correttamente gli argomenti, ma come ha suggerito Eddie Kelley, è necessario inserirne uno nella parte anteriore. Indica a boinccmd che lo hai invocato come "--host", quindi ha passato altri sei argomenti. boinccmd è in grado di riconoscere le ultime cinque come due opzioni, ma non ha idea di cosa sia il business "localhost". Per quanto boinccmd può dire, è stato invocato dal terminale come

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

(notare il "--host" mancante).

boinccmd è probabilmente uno della stragrande maggioranza dei programmi a cui non importa quale sia il loro primo argomento, quindi probabilmente potresti semplicemente spingere <string>HELLO</string>in testa alla ProgramArgumentsmatrice, ma è probabilmente più pulito rimuovere del Programtutto la chiave e usare solo 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 insignificante, ma alcuni programmi lo usano con buoni risultati: bash et al. agire come shell di login se il loro primo argomento inizia con -, e Vim entra in varie modalità di emulazione se il suo primo argomento è edo viinvece di vim.


1
Hai pubblicato mentre stavo modificando il mio post principale! Questa è un'ottima spiegazione Grazie.
Woodgie,

1
Sono contento di essere d'aiuto :)
SirPavlova,

@SirPavlova, grande aiuto! Tuttavia, esiste uno strumento che aiuta la persona a convertire l'invocazione della console nel formato plist?
gaussblurinc,

6

Sulla base della pagina man di 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 nell'indice 0, può aiutare ...


Come ho modificato il post per mostrare, il boinccmd viene trovato ed eseguito, le opzioni che gli vengono passate vengono in qualche modo alterate. A meno che non mi manchi quello che stai dicendo.
Woodgie,

1
@Woodgie Sì, che è stato trovato nel Programma - il tuo ProgramArguments è errato ha bisogno del nome del percorso dell'eseguibile
user151019

Oh. OH! Penso di vedere ora. Aspetta, lasciami provare.
Woodgie,

BINGO, farlo e mettere ogni parte di ogni comando nel suo contenitore <string> </string> ha funzionato. Grazie. Ti ho detto che era semplice!
Woodgie,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.