Как зарегистрировать агента с помощью launchd

14

Я не могу запланировать периодический запуск с launchctl/ launchdна OS X (Leopard). По сути, я не могу найти пошаговый список инструкций в Интернете, и интуитивный подход не работает.

sync.plistФайл:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>net.madrat.utils.sync</string>
        <key>Program</key>
        <string>rsync</string>
        <key>ProgramArguments</key>
        <array>
            <string>-ar</string>
            <string>/path/to/folder/</string>
            <string>/path/to/backup/</string>
        </array>
        <key>StartInterval</key>
        <integer>7200</integer>
    </dict>
</plist>

Я поместил этот скрипт в путь ~/Library/LaunchAgents.

Далее я зарегистрировал скрипт, используя

launchctl load ~/Library/LaunchAgents/sync.plist

Наконец, чтобы проверить, что это работает, я начал работу:

 launchctl start net.madrat.utils.sync

- Ничего не произошло. Выполнение rsyncкоманды в терминале вручную дает ожидаемый результат.

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

Что я сделал не так?

Конрад Рудольф
источник

Ответы:

5

Lingon - хороший графический инструмент для управления запуском. Проект, похоже, сейчас не поддерживается ... но он определенно все еще работает на 10.5.x.

Но к вашей конкретной проблеме ... вы пробовали

sudo launchctl list 

Это скажет вам, если .plist срабатывает правильно. Он вернет 1, если демон не запускается, и 0, если он успешен. Может быть, искать это.

Всякий раз, когда я вижу «1», это обычно потому, что я поставил скрипт не в том месте, сделал опечатку или неправильно установил разрешения.

Также .... перезагрузка часто .. Я видел

launchctl start

не быть эффективным, когда перезагрузка была ..

Кроме того, если рассмотреть ваш вопрос поближе ... почему бы просто не поместить этот код rsync в скрипт bash ... и вставить его в /usr/bin/..... Тогда вы можете просто chmod+xэтот файл .... и упростить свой .plist запустить этот скрипт, когда захотите ....

CaseyIT
источник
Спасибо, поместив команду в дополнительный файл оболочки и запустив , все получилось. Это очень неудовлетворительное решение, хотя ... почему вызов команды не работает напрямую? Кстати, launchctl list сделал дисплей 1, но только после того, как я начал агент вручную с помощью launchctl start.
Конрад Рудольф
Я не уверен, но я думаю, что файлы launchd .plist на самом деле просто предназначены для определения критериев запуска по требованию для демонов ... Возможно, он не был уверен, что делать с аргументами, которые вы передали в <key> ProgramArguments </ ключ>.
CaseyIT
11

Длинный ответ:

Трудно работать с launchd без понимания некоторых основных принципов. Так что, скорее всего, вы не найдете пошаговую инструкцию, у нее столько возможностей. Хорошим шагом будет руководство по началу работы на АЦП: http://developer.apple.com/macosx/launchd.html

Вы также можете прочитать страницы руководства для launchd, launchctlи .plist синтаксис файлов, launchd.plist.

Часто возникает недоразумение, куда поместить вашего агента или демона, поэтому позвольте мне рассказать об этом здесь:

  • Если ваша работа должна выполняться, даже если ни один пользователь не вошел в систему, поместите ее в / Library / LaunchDaemons.
  • Если это полезно только при входе пользователей в систему, поместите его в / Library / LaunchAgents или в личные каталоги LaunchAgents определенных пользователей (~ / Library / LaunchAgents).
  • Не помещайте свою работу в / System / Library, которая зарезервирована для системных демонов.
~/Library/LaunchAgents         Per-user agents provided by the user.
/Library/LaunchAgents          Per-user agents provided by the administrator.
/Library/LaunchDaemons         System wide daemons provided by the administrator.
/System/Library/LaunchAgents   Mac OS X Per-user agents.
/System/Library/LaunchDaemons  Mac OS X System wide daemons.

Короткий ответ:

Возможно, имя вашего plist-файла неверно, сейчас я не могу его проверить, но я бы установил его net.madrat.utils.sync.plist. Также может быть полезно сначала unloadзагрузить свой демон перед загрузкой, если вы отредактировали файл.

Arko
источник
Спасибо за информацию. Однако: (1) Я уже прочитал все документы, на которые вы ссылались выше, и еще несколько. Нигде не сказано, как запустить агента. (По крайней мере, я нигде не нашел.) Это было бы хорошо, если бы мой интуитивный подход работал. (2) Изменение имени файла также не работает. :-( (3) некоторая информация устарела. Например, они предлагают команду launchd bashдля отладки - но она не работает на Leopard ( launchdне может быть запущена напрямую).
Конрад Рудольф,
@Konrad Rudolph: Пожалуйста: :) @Skylarking получает несколько интересных моментов: вы проверили наличие файла? Или использовал команду sudo? Мне также приходилось иногда перезагружаться, чтобы launchctl работал правильно.
Арко
3

Я не могу найти документацию, что это на самом деле стандартное поведение, но кажется, что launchd требует абсолютных путей в файлах plist. Так что попробуйте /usr/bin/rsyncвместо этого. Работает для меня!

Эрик Шостер
источник
0

попробуйте это, мои сценарии работают без использования программной части, просто программные аргументы ...

замещать

    <key>Program</key>
    <string>rsync</string>
    <key>ProgramArguments</key>
    <array>
        <string>-ar</string>
        <string>/path/to/folder/</string>
        <string>/path/to/backup/</string>
    </array>

с

    <key>OnDemand</key>
    <true/>
    <key>ProgramArguments</key>
    <array>
        <string>rsync</string>
        <string>-ar</string>
        <string>/path/to/folder/</string>
        <string>/path/to/backup/</string>
    </array>
Бекки
источник
0

попробуйте добавить эти ключи в ваш файл plist

    <key>KeepAlive</key>
    <true/>
    <key>RunAtLoad</key>
    <true/>
проворный
источник
0

В вашем файле .plist есть одна неправильная вещь и одна хитрая (каждая из этих точек была затронута в предыдущих ответах; я собираю их здесь).

Вы бы лучше написали:

<key>ProgramArguments</key>
<array>
  <string>/usr/local/bin/rsync</string>
  <string>-ar</string>
  <string>/path/to/folder/</string>
  <string>/path/to/backup/</string>
</array>

Первым аргументом в ProgramArgumentsмассиве является программа, которую нужно выполнить - вы бы ее пропустили. Если Programключ опущен, то по умолчанию используется первый аргумент ProgramArguments; вероятно, целесообразно указать это только один раз.

Поскольку вы пропустили этот первый аргумент, ваш .plist будет вызывать rsync (через имя в Program), но «первый аргумент» rsync был бы /path/to/folder, а не -ar(запущенная программа будет очень кратко видна в psвыходных данных, прежде чем она выйдет с ошибка, но названная как -ar, что является содержанием нулевого аргумента).

Вам не нужно указывать путь к нему rsync, но в этом контексте, вероятно, целесообразно сделать это, чтобы не полагаться на то, PATHчто он установлен соответствующим образом.

Документация для этого находится в launchd.plist(5). Обратите внимание, что на этой странице подчеркивается, что значение ProgramArgumentsключа передается execvp(3). Это execvpстраница руководства, которая объясняет поиск PATH.

Норман грей
источник