13.01.13

Запуск собственных скриптов systemd


Через rc.local

Как и ранее, чтобы запустить какой-то скрипт при загрузке системы, вы можете поместить его в файл /etc/rc.d/rc.local. Однако стоит учесть специфику запуска этого скрипта в systemd.
service-файл отвечающего за него юнита выглядит следующим образом:
$ cat /lib/systemd/system/rc-local.service
[Unit]
Description=/etc/rc.d/rc.local Compatibility
After=network.target

[Service]
Type=forking
ExecStart=/etc/rc.d/rc.local start
TimeoutSec=0
RemainAfterExit=yes
SysVStartPriority=99
Отсюда видно, во-первых, что файл /etc/rc.d/rc.local обязан быть исполняемым.
А во-вторых, видно, что сервис rc-local имеет зависимость только от цели network.target. Параметр SysVStartPriority=99 отвечает только за приоритет по сравнению с другими sysVinit-скриптами, которых в Fedora становится все меньше. С учетом параллельной загрузки это означает, что скрипт, который вы разместите в файле rc.local может быть запущен слишком рано, например, до старта нужных сервисов. Поэтому, если вы разместите в этом файле скрипты перезапуска апача, то, с большой вероятностью, они не сработают.
В версиях до Fedora 17, не было зависимости от network.target, так что, там этот скрипт запускался практически в самом начале.

С помощью systemd-юнита

Более естественный для systemd способ запускать скрипты - это создание своего собственного юнита.
Просто создайте файл /etc/systemd/system/my_stuff.service со следующим текстом:
[Unit]
Description=Run my stuff  
Requires=network.target   
After=network.target 
 
[Service]
Type=oneshot
RemainAfterExit=True
ExecStart=/some/script --with-some-parameters
ExecStart=/some/other/script
 
[Install]
WantedBy=multi-user.target
Здесь Requires - указывает цель, после которой необходимо запустить сервис, After означает, что сеть должна быть полностью запущена к моменту старта, WantedBy - цель, для которой запускается сервис. В ExecStart должен быть указан полный путь к скрипту или исполняемому файлу, поскольку переменная PATH не используется.
multi-user.target - это аналог init 3 в sysVinit. Подробнее о реализации runlevel-ов в systemd, можно прочесть по ссылке.
В такой конфигурации скрипты будут запускаться сразу после запуска сети и старта всех интерфейсов. Однако systemd позволяет гораздо более гибкую настройку. Например, для выполнения скриптов после запуска графического DM можно использовать After: systemd-user-sessions.service
Небольшой пример: После появления облачного хранилища Яндекс.Диск, захотелось автоматически монтировать его в файловую систему через davfs2 (с заранее положенными логином и паролем в /etc/davfs2/secrets). Прописывание в fstab не дало результатов, как и прописывание в rc.local, поскольку в Fedora 16 оба они обрабатывались ещё до поднятия сети. А вот создание модуля по вышеприведённому образцу решило проблему.

Дополнительно

Для диагностики сервиса используйте команду
systemctl status rc-local.service
или загляните в файл /var/log/boot.log (он появится если в параметрах загрузки убрать quiet, см. Grub2).