Следующая новость
Предыдущая новость

Контролируемый пуск. Автоматизируем macOS при помощи Python и launchctl

16.02.2018 13:35
Контролируемый пуск. Автоматизируем macOS при помощи Python и launchctl

Содержание статьи

  • Агенты и демоны
  • Простой конфиг: запуск по времени
  • Тонкости активации
  • Настраиваем скачивание сериалов
  • Пишем свой «дропбокс»
  • Бэкапим и шифруем данные при подключении флешки
  • Другие возможности
  • Итоги

Launchctl — это утилита, которая знакома каждому опытному маководу, но при этом многие избегают связываться с ней лишний раз. А зря! Этот универсальный лаунчер — один из важнейших компонентов системы. Изучив его настройки, ты сможешь делать массу интересных и полезных вещей. Я покажу три примера того, как launchctl может пригодиться в жизни.

INFO

Эта статья — уже третья из моего небольшого цикла о macOS. В первой («Обвес macOS») мы изучали скрытые настройки и собирали полезный софт, во второй («Кунг-фу для маковода») прошлись по большинству уникальных утилит командной строки. В ней я уже касался launchctl, но лишь вкратце. Что эта штука достойна отдельной статьи, было ясно сразу.

Благодаря гибкости настроек launchd, этот сервис заменил в macOS целый список более старых систем, которые пришли из Unix. Он управляет процессом загрузки ОС и сервисов (вместо init), он реагирует на подключения по сети (вместо inetd), он же запускает скрипты по времени (вместо cron) и при разных условиях. Мы воспользуемся этими богатыми возможностями для настройки всякой автоматизации: запуска скриптов по времени, срабатывания при помещении файла в папку, при изменении файла и при подключении внешнего носителя.

Я буду писать именно про launchctl, поскольку работаю в macOS, но если ты предпочитаешь Linux, то можешь позаимствовать идеи и скрипты, которые мы будем писать, и проделать все то же самое при помощи systemd. Эта система похожа на launchd и есть во многих современных дистрибутивах. Однако ее настройки в корне отличаются, и параллельно разбирать еще и их я не возьмусь.

Ты уже когда-нибудь писал себе скрипты, которые работают по расписанию?

  • Да, вовсю использую!
  • Нет, бог миловал
  • Пока нет, но есть пара идей

Контролируемый пуск. Автоматизируем macOS при помощи Python и launchctl Загрузка …

Агенты и демоны

Файлы с правилами — это XML с расширением .plist. Внутри содержатся инструкции, которые указывают launchd, что и когда запускать. Эти файлы разложены в системе по пяти папкам:

  • ~/Library/LaunchAgents — агенты текущего пользователя;
  • /Library/LaunchAgents — агенты для всех пользователей;
  • /Library/LaunchDaemons — демоны для всех пользователей;
  • /System/Library/LaunchAgents — системные агенты (входят в состав macOS);
  • /System/Library/LaunchDaemons— системные демоны.

Отличие агентов от демонов довольно тонкое: демоны — это процессы, которые запускаются сразу после загрузки машины, а агенты могут работать только после логина в систему (соответственно, демонов для конкретного пользователя не бывает). К тому же демоны после активирования работают непрерывно, а агенты обычно срабатывают при определенных условиях.

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

Контролируемый пуск. Автоматизируем macOS при помощи Python и launchctl

WWW

Для создания конфигурационных файлов launchd есть пара графических оболочек — LaunchControl и Lingon (обе стоят по десять долларов). Они слегка облегчают дело, но можно обойтись и без них.

Простой конфиг: запуск по времени

Начнем с самого простого — запуска чего-нибудь в определенное время. Вот как выглядит один из самых простых вариантов конфига.

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict>         <key>Label</key>         <string>название</string>         <key>ProgramArguments</key>         <array>                 <string>путь к файлу</string>         </array>         <key>StartCalendarInterval</key>         <dict>                 <key>Minute</key><integer>30</integer>                 <key>Hour</key><integer>1</integer>                 <key>Day</key><integer>6</integer>         </dict> </dict> </plist> 

Несмотря на развесистый вид, структура здесь довольно несложная. Внутри основного словаря (<dict>) идут ключи и следом — параметры к ним. Иногда это строки, иногда массивы, иногда вложенные словари.

Заменяй слово «название» на какое-нибудь название (обычно «com.домен.имя» — я, например, назвал тестовый агент com.and.launchtest), укажи путь к исполняемому файлу в качестве первого параметра ProgramArguments, а затем задай, во сколько и по каким дням запускать.

Контролируемый пуск. Автоматизируем macOS при помощи Python и launchctl
Конфиги удобно редактировать в Xcode

В примере выставлено время 1:30 каждую субботу. Если ты снесешь ключ Day, скрипт начнет запускаться в половине второго каждую ночь, а если уберешь и Hour, то каждые полчаса. Думаю, ты понял идею. Аналогичная запись в crontab выглядела бы как

0 30 1 * 6 <путь к файлу> 

Если команда, которую ты запускаешь, принимает аргументы, то их нужно перечислить после пути, добавив дополнительные поля <string>. Например:

<key>ProgramArguments</key> <array>         <string>say</string>         <string>В Петропавловске-Камчатском полночь</string> </array> <key>StartCalendarInterval</key> <dict>         <key>Minute</key><integer>0</integer>         <key>Hour</key><integer>15</integer> </dict> 

Когда все будет готово, сохраняем файл в ~/Library/LaunchAgents/. Хорошей идеей будет сразу прописать в названии условия запуска, чтобы потом было легче ориентироваться. Например, мой тестовый конфиг я сохранил как com.and.launchtest.StartInterval.plist.

Кстати, что ты думаешь об XML?

  • Гениальная штука!
  • Не так плохо, но лучше использовать JSON
  • Это ужасно, что угодно лучше, чем это

Контролируемый пуск. Автоматизируем macOS при помощи Python и launchctl Загрузка …

Тонкости активации

К сожалению, обратная сторона гибкости — это развесистость настроек. Даже включать и выключать конфиги launchd можно несколькими способами. Вот старый и наиболее простой. Для загрузки пиши:

$ launchctl load -w ~/Library/LaunchAgents/<конфиг.plist> 

И для выгрузки:

$ launchctl unload -w ~/Library/LaunchAgents/<конфиг.plist> 

Ключ -w заодно включает флаг enabled, что экономит нам один шаг (launchctl enable) и сразу активирует конфиг. Помни, что после загрузки компьютера и входа в систему все агенты, лежащие в соответствующих папках, будут загружены автоматически. Именно поэтому при выгрузке удобно тоже добавлять -w — тогда launchctl запомнит, что конфиг неактивен.

Контролируемый пуск. Автоматизируем macOS при помощи Python и launchctl

INFO

После того как что-то меняешь в конфиге, его нужно выгружать и загружать заново.

Можешь спокойно пользоваться этими командами, однако если откроешь man, то узнаешь, что они считаются устаревшими и поддерживаются лишь для совместимости. Более правильный способ — использовать команды bootstrap и bootout. Они требуют указывать, помимо пути к файлу конфигурации, domain-target, который состоит из домена и UID пользователя. Целиком команды будут выглядеть вот так:

$ launchctl bootstrap gui/<твой UID> <путь к файлу> 

И для выгрузки:

$ launchctl bootout gui/<твой UID> <путь к файлу> 

Узнать свой UID можешь командой id -u. Первый пользователь компьютера обычно записан под номером 502.

Другая команда, которую хорошо помнить, — это list. Чтобы проверить, какие из твоих конфигов загружены, можешь написать:

$ launchctl list | grep <название> 
Контролируемый пуск. Автоматизируем macOS при помощи Python и launchctl

Опять же — существует более современный, более продвинутый и, конечно, более замороченный метод:

$ launchctl print <домен>/<UID> 

На выходе будет куда больше информации, чем при запросе списка. Но опять же, использовать print совершенно не обязательно. В ответ на вопрос о том, когда устаревшие команды перестанут работать, кто-то из разработчиков ответил на форуме, что на старый синтаксис слишком много завязано, чтобы убирать его.

Продолжение статьи доступно только подписчикам

Cтатьи из последних выпусков журнала можно покупать отдельно только через два месяца после публикации. Чтобы читать эту статью, необходимо купить подписку.

Подпишись на журнал «Хакер» по выгодной цене!

Подписка позволит тебе в течение указанного срока читать ВСЕ платные материалы сайта, включая эту статью. Мы принимаем оплату банковскими картами, электронными деньгами и переводами со счетов мобильных операторов. Подробнее о подписке

1 год

6190 р.

Экономия 1400 рублей!

1 месяц

720 р.

25-30 статей в месяц

Уже подписан?

Источник

Последние новости