Початок запуску для правильного читання аргументів програми


18

У мене є запущений скрипт, де команда, яку я намагаюся запустити, помиляється (мабуть, це не слово, це зараз), скаржиться на неправильне використання.

Конкретна помилка, яку я отримую, - це текст використання команди, скинутий у системний журнал. З цього я випливаю іншу інформацію (шлях до команди, синхронізацію і т. Д.) В плісті аналізується правильно, тільки не параметри команди.

Після використання команди у мене є останній рядок:

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

Але це просто означає "я вийшов з помилкою".

Я знаю, що запускає розділяє команду від її параметрів, і на сторінці man розповідає про ProgramArguments: "... Зауважте: багато людей плутають цей ключ. Будь ласка, прочитайте execvp (3) дуже уважно! .."

Ну я читаю execvp (3), і я не мудріший, тому я прошу вас прекрасно.

Зазвичай, запускаючи команду з терміналу, вона виглядатиме так:

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

Це працює частування.

Ось як я розділив це в розділі Програми / Програми Аргументів мого списку 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>

(для запису, я спочатку мав шлях до boinccmd \ escape, але це не працює, запускаючи втечу пробілів у шляху для вас)

Я намагався розділити аргументи далі:

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

Але це теж не здавалося.

Як завжди, я впевнений, що мені не вистачає чогось такого простого.

Спасибі.


ВІДПОВІДЬ:

Першим рядком програмних аргументів повинен бути шлях до програми. Це те, що мене спонукало, і справді те, що, мабуть, означало коментар "... Будь ласка, читайте дуже уважно! .." :) Я також виявив, що мені довелося розділити аргументи на їх складові частини. Коли я мав все це на місці, то ця річ приваблива. Велике спасибі.

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

Останню редакцію, щоб сказати, щоб зрозуміти пояснення щодо того, ЧОМУ це має бути, дивіться в поясненні СерПавлова.

~ Ш


Використовуючи список startctl com.label.plist, я можу побачити, що запускаючий файл отримує правильні частини команди разом. Я думав, можливо, це була проблема, пов'язана з -, але, мабуть, ні.
Вудді

1
У мене немає відповіді на вашу проблему, але ваш перший приклад <string>--host localhost</string>точно не вийде . Пам'ятайте, що коли ви пишете командний рядок в оболонку, він не має уявлення про те, що є частиною параметра і що є звичайним аргументом - він просто розбивається на пробіли, перш ніж передавати аргументи запущеній програмі. Також це може допомогти, якщо ви мали б показати точну помилку, про яку boinccmdповідомляється.
Кевін Рейд

Редагував свою публікацію, щоб сказати, що я бачу. Не те, що це допоможе! Крім того, я отримую ту ж помилку, якщо розділяю параметри на їх пробіл. Я здогадуюсь, що це те, що викликає проблему якось.
Woodgie

1
Я б спробував використати лише Програму або Програмні аргументи не обидва
user151019

Відповіді:


19

У Programключових вказує файл для виконання, і ProgramArgumentsключ визначає аргументи , які будуть передані в процесі виконавчого. Строго кажучи, ви можете передавати будь-які аргументи, які ви хочете, щоб процес, але умовою є те, що перший повинен бути ім'ям, за допомогою якого викликався процес, тому більшість програм ігнорує свій перший аргумент. Файл, який потрібно виконати, - це, очевидно, необхідна інформація, але якщо Programключ відсутній, запускається, що запускається, робить вигляд, що він має те саме значення, що і перший аргумент, ProgramArguments просто як зручність .

Ваш перший приклад запускає boinccmd і надає йому аргументи, які були б еквівалентні команді терміналу

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

який повідомляє boinccmd, що ви викликали його як "--host localhost" і передавали йому лише два дивні аргументи.

У вашому другому прикладі аргументи правильно розділені, але, як висловив думку Едді Келлі, йому потрібен один, вставлений в передній частині. Він повідомляє boinccmd, що ви викликали його як "--host", а потім передали ще шість аргументів. boinccmd може визнати останні п'ять як два варіанти, але не має уявлення про те, про що йдеться у "localhost". Наскільки boinccmd може сказати, його викликали з терміналу як

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

(відзначте пропущене "--гост").

boinccmd - це, мабуть, одна з великої більшості програм, яким не байдуже, який їх перший аргумент, тому ви, мабуть, могли насправді просто засунути <string>HELLO</string>на голову ProgramArgumentsмасиву, але, ймовірно, чистіше видалити Programключ і просто скористатися цим:

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

Це може здатися безглуздим надмірністю, але деякі програми використовують це для хорошого ефекту: bash et al. діють як оболонки входу, якщо їх перший аргумент починається -, і Vim переходить у різні режими емуляції, якщо його перший аргумент є edабо viзамість нього vim.


1
Ви публікували, коли я редагував основну публікацію! Це чудове пояснення. Дякую.
Вудджі

1
Радий, що вам допоможуть :)
СерПавлова

@SirPavlova, чудова допомога! Однак чи є якийсь інструмент, який допомагає людині конвертувати виклик консолі у формат плістів?
gaussblurinc

6

Виходячи зі сторінки man для exec (3), здається, що першим програмним аргументом повинен бути шлях до виконуваного файлу:

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.

Якщо ви можете вказати шлях до виконуваного файлу як аргумент в індексі 0, це може допомогти ...


Коли я редагував публікацію для показу, boinccmd знаходить і запускає, а варіанти, що передаються йому, якимось чином піддаються перевірці. Якщо я не пропускаю те, що ти кажеш.
Вудджі

1
@Woodgie Так, що було знайдено в Програмі - ваші ProgramArguments неправильні, йому потрібна назва шляху виконуваного файлу
user151019

Ой. О! Я думаю, що зараз бачу. Почекай, тест леме.
Woodgie

BINGO, зробивши це і поклавши кожну частину кожної команди у свій контейнер <string> </string>, працював. Дякую. Я сказала вам, що це було просто!
Woodgie
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.