Начало запуска, чтобы правильно прочитать аргументы программы

18

У меня есть скрипт launchd, в котором команда, которую я пытаюсь выполнить, содержит ошибку (очевидно, это не слово, это сейчас), жалуясь на неправильное использование.

Конкретная ошибка, которую я получаю, - это текст использования команды, выгруженный в системный журнал. Из этого я делаю вывод, что другая информация (путь к команде, время и т. Д.) В plist анализируется правильно, но не параметры команды.

После использования команды у меня есть последняя строка:

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

Но это просто означает, что «я вышел с ошибкой».

Я знаю, что launchd разбивает команду по ее параметрам и на странице руководства рассказывает о ProgramArguments: «... Обратите внимание: многие люди смущены этим ключом. Пожалуйста, внимательно прочитайте execvp (3)! ..»

Ну, я прочитал execvp (3), и я не мудрый, поэтому я вас очень прошу.

Обычно при запуске команды из терминала это выглядит так:

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

Это работает удовольствие.

И вот как я разделил это в разделе Program / ProgramArguments моего списка 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 \ escaped, но это не работает, launchd избегает пробелов в пути для вас)

Я попытался разделить аргументы дальше:

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

Но это тоже не сработало.

Как всегда, я уверен, что мне не хватает чего-то такого простого.

Благодарю.


ОТВЕТ:

Первая строка ProgramArguments должна быть путем к программе. Это то, что меня сбило с толку, и, действительно, то, что, вероятно, подразумевалось под комментарием «... Пожалуйста, прочитайте очень внимательно! ..» :) Я также обнаружил, что мне пришлось разделить аргументы на их составные части. Когда у меня все это было на месте, все это создает очарование. Большое спасибо.

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

Окончательное редактирование, чтобы сказать для легкого для понимания объяснения ПОЧЕМУ это должно быть, см. Объяснение сэра Павлова.

~ W

Woodgie
источник
С помощью launchctl list com.label.plist я вижу, что launchd собирает правильные части команды для объединения. Я думал, может быть, это была проблема, связанная с -, но, видимо, нет.
Вуджи
1
У меня нет ответа на вашу проблему, но ваш первый пример с <string>--host localhost</string>определенно не сработает. Помните, что когда вы пишете командную строку в оболочку, она не имеет представления о том, что является частью опции и что является обычным аргументом - она ​​просто разделяется на пробелы перед передачей аргументов в выполняемую программу. Кроме того, это могло бы помочь, если бы вы показывали точную ошибку, которая boinccmdсообщает.
Кевин Рид
Отредактировал мой пост, чтобы сказать, что я вижу. Не то чтобы это помогло! Кроме того, я получаю ту же ошибку, если я разделяю параметры в их пробелах. Я предполагаю, что это - это как-то вызывает проблему.
Вуджи
1
Я бы попробовал использовать только Program или ProgramArguments, а не оба
user151019

Ответы:

19

В Programключевых указывает файл для выполнения, и ProgramArgumentsключ определяет аргументы , которые будут переданы в процессе исполнительного. Строго говоря, вы можете передавать любые аргументы, которые хотите, процессу, но общепринятым является то, что первым должно быть имя, по которому был вызван процесс, поэтому большинство программ игнорируют свой первый аргумент. Файл для выполнения, очевидно, является необходимой информацией, но если Programключ отсутствует, launchd делает вид, что он имеет то же значение, что и первый аргумент, 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

(обратите внимание на отсутствующий "--host").

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.

SirPavlova
источник
1
Вы опубликовали, как я редактировал мой главный пост! Это отличное объяснение. Спасибо.
Вудги
1
Рад быть
полезным
@SirPavlova, отличная помощь! Тем не менее, есть ли инструмент, который помогает человеку конвертировать вызов консоли в формате plist?
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 Да, это было найдено в Program - ваши ProgramArguments неверны, ему нужен путь к исполняемому файлу
user151019
Ой. ОЙ! Я думаю, что я вижу сейчас. Подожди, дай мне проверить это.
Вудги
БИНГО, сделав это и поместив каждую часть каждой команды в свой собственный контейнер <string> </ string>. Спасибо. Я сказал тебе, это было просто!
Вудги