Uruchomienie w celu poprawnego odczytania argumentów programu

18

Mam uruchomiony skrypt, w którym polecenie, które próbuję uruchomić, jest błędne (najwyraźniej to nie jest słowo, jest teraz), narzeka na niewłaściwe użycie.

Konkretny błąd, który otrzymuję, to tekst użycia polecenia zrzucony do dziennika systemu. Z tego wnioskuję, że inne informacje (ścieżka do polecenia, czas itp.) W liście są analizowane poprawnie, tylko nie opcje polecenia.

Po użyciu polecenia mam ostatnią linię:

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

Ale to po prostu oznacza „wyszedłem z błędem”.

Wiem, że uruchomione dzieli polecenie z jego opcji, a na stronie podręcznika mówi o ProgramArguments: „... Uwaga: wiele osób jest zdezorientowanych tym kluczem. Proszę bardzo uważnie przeczytać execvp (3)! ..”

No cóż, czytam execvp (3) i nie jestem mądrzejszy, więc proszę bardzo o cudowne pytania.

Zwykle uruchomienie polecenia z terminala wyglądałoby tak:

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

To działa na ucztę.

I w ten sposób podzieliłem go w sekcji Program / ProgramArguments mojej listy 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>

(dla przypomnienia, pierwotnie miałem ścieżkę do boinccmd \ uciekł, ale to nie działa, uruchomiłem dla ciebie spacje na ścieżce)

Próbowałem dalej podzielić argumenty:

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

Ale to też nie działało.

Jak zawsze jestem pewien, że brakuje mi czegoś tak prostego.

Dzięki.


ODPOWIEDŹ:

Pierwszy wiersz ProgramArguments musi być ścieżką do programu. Właśnie to mnie potknęło i to prawdopodobnie oznaczało komentarz „... Proszę bardzo uważnie przeczytać! ..” :) Stwierdziłem również, że musiałem podzielić argumenty na części składowe. Kiedy wszystko to miałam na swoim miejscu, to wszystko działa jak urok. Dziękuję Ci bardzo.

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

Ostateczna edycja do łatwego zrozumienia wyjaśnienia, DLACZEGO to powinno być, zobacz wyjaśnienie SirPavlova.

~ W

Woodgie
źródło
Korzystając z listy launchctl com.label.plist, widzę, że launchd zbiera odpowiednie części polecenia. Myślałem, że może to był problem związany z - ale najwyraźniej nie.
Woodgie
1
Nie mam odpowiedzi na twój problem, ale twój pierwszy przykład na <string>--host localhost</string>pewno nie zadziała. Pamiętaj, że kiedy piszesz wiersz poleceń w powłoce, nie ma pojęcia, co jest częścią opcji i co to jest zwykły argument - po prostu dzieli się spacjami przed przekazaniem argumentów do uruchamianego programu. Może to również pomóc, jeśli chcesz pokazać dokładnie boinccmdzgłaszany błąd .
Kevin Reid
Edytowałem mój post, aby powiedzieć, co widzę. Nie żeby to pomogło! Otrzymuję ten sam błąd, jeśli podzielę opcje na białe znaki. Zgaduję, że to - to w jakiś sposób powoduje problem.
Woodgie,
1
Spróbowałbym użyć tylko Programu lub ProgramArguments, a nie obu
user151019,

Odpowiedzi:

19

Do Programkluczowych Określa plik do wykonania, & the ProgramArgumentskey określa argumenty, które zostaną przekazane do procesu wykonującego. Ściśle mówiąc, możesz przekazać dowolne argumenty do procesu, ale konwencja jest taka, że ​​pierwsza powinna być nazwą, pod którą wywołano proces, więc większość programów ignoruje swój pierwszy argument. Plik do wykonania jest oczywiście niezbędną informacją, ale jeśli Programbrakuje klucza, uruchomienie udaje, że ma taką samą wartość jak pierwszy argument ProgramArguments wyłącznie dla wygody .

Twój pierwszy przykład zaczyna się od boinccmd i podaje mu argumenty, które byłyby równoważne poleceniu terminalu

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

co mówi boinccmd, że wywołałeś go jako „--host localhost” i przekazałeś mu tylko dwa dziwne argumenty.

Drugi przykład poprawnie rozdziela argumenty, ale jak sugerował Eddie Kelley, należy go wstawić z przodu. Mówi boinccmd, że wywołałeś go jako „--host”, a następnie przekazałeś kolejne sześć argumentów. boinccmd rozpoznaje ostatnie pięć jako dwie opcje, ale nie ma pojęcia o czym jest biznes „localhost”. O ile boinccmd może powiedzieć, został wywołany z terminala jako

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

(zwróć uwagę na brakujący „--host”).

boinccmd jest prawdopodobnie jednym z przeważającej większości programów, które nie dbają o to, jaki jest ich pierwszy argument, więc prawdopodobnie prawdopodobnie po prostu wepchniesz się <string>HELLO</string>na czoło ProgramArgumentstablicy, ale prawdopodobnie łatwiej jest usunąć Programklucz i po prostu użyć tego:

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

Może to wydawać się pozbawioną znaczenia redundancją, ale niektóre programy wykorzystują to z dobrym skutkiem: bash i in. działają jako powłoki logowania, jeśli ich pierwszy argument zaczyna się od -, a Vim wchodzi w różne tryby emulacji, jeśli jego pierwszym argumentem jest edlub vizamiast niego vim.

SirPavlova
źródło
1
Napisałeś, gdy edytowałem mój główny post! To świetne wytłumaczenie. Dziękuję Ci.
Woodgie,
1
Cieszę się, że
mogłem
@SirPavlova, świetna pomoc! Czy jest jednak jakieś narzędzie, które pomaga przekonwertować wywołanie konsoli na format plist?
gaussblurinc
6

Na podstawie strony podręcznika dla exec (3) wydaje się, że pierwszym argumentem programu powinna być ścieżka do pliku wykonywalnego:

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.

Jeśli możesz podać ścieżkę do pliku wykonywalnego jako argument w indeksie 0, może to pomóc ...

Eddie Kelley
źródło
Gdy edytowałem post, aby pokazać, boinccmd jest znajdowany i uruchamiany, opcje przekazywane do niego są w jakiś sposób zniekształcane. Chyba że brakuje mi tego, co mówisz.
Woodgie,
1
@Woodgie Tak, który został znaleziony w Programie - Twój ProgramArguments jest niepoprawny, potrzebuje nazwy ścieżki pliku wykonywalnego
użytkownik151019,
O. O! Myślę, że teraz widzę. Poczekaj, przetestuj to.
Woodgie,
BINGO, robi to i umieszcza każdą część każdej komendy w swoim własnym <string> </string> kontenerze. Dziękuję Ci. Mówiłem wam, że to było proste!
Woodgie,