Как зарегистрировать агента с помощью 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/>