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

INFO

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

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

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

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

Загрузка ... Загрузка ...
 

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

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

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

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

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

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, а затем задай, во сколько и по каким дням запускать.

Конфиги удобно редактировать в Xcode
Конфиги удобно редактировать в 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?

Загрузка ... Загрузка ...
 

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

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

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

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

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

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

INFO

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

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

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

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

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

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

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

$ launchctl list | grep <название>

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

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

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

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

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Вариант 2. Открой один материал

Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    8 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии