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

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

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 Команда в терминале дает ожидаемый результат.

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

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

6 ответов

Решение

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

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

sudo launchctl list 

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

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

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

launchctl start

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

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

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

Трудно работать с 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 ваш демон перед загрузкой, если вы редактировали файл.

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

В вашем файле.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 man-страница, которая объясняет о поиске PATH.

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

замещать

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

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

    <key>KeepAlive</key>
    <true/>
    <key>RunAtLoad</key>
    <true/>
Другие вопросы по тегам