Как сделать сервис systemd последним при загрузке?

26

Много лет назад мы можем написать наш скрипт запуска /etc/rc.local. После загрузки всех системных служб ваш скрипт будет запущен.

Теперь мы используем systemd, у нас rc.localбольше нет. Systemd запускает службу параллельно. Вы можете написать свой собственный сервис для работы с rc.local`, но не можете гарантировать, что он будет работать после загрузки всех системных сервисов.

Есть ли способ сделать это? Или мы должны использовать Beforeи Afterв файле службы systemd?

比尔 盖子
источник
5
Systemd, а не Upstart!
Jan 盖子
Укажите название и версию ОС?
STTR
ОС: Arch Linux, Версия: N / A
比尔 盖子
1
@ 比尔 盖子 Почему «последний», вы не знаете зависимости скрипта или хотите, чтобы он был последним просто для безопасности?
Пол

Ответы:

27

В systemd рекомендуется использовать Before=и After=упорядочивать ваши услуги рядом с другими.

Но так как вы просили путь без использования Beforeи After, вы можете использовать:

Type=idle

который как man systemd.serviceобъясняет:

Поведение idleочень похоже на simple; однако фактическое выполнение сервисной программы откладывается до тех пор, пока не будут отправлены все активные задания. Это может использоваться, чтобы избежать чередования вывода служб оболочки с выводом статуса на консоли. Обратите внимание, что этот тип полезен только для улучшения вывода на консоль, он не полезен в качестве общего инструмента упорядочения модулей, и эффект этого типа сервиса зависит от времени ожидания 5 с, после которого сервисная программа вызывается в любом случае.

SimonPe
источник
1
Привет, не могли бы вы разработать синтаксис, если я собираюсь использовать до или после?
r4ccoon
Несколько другая тема, но если кто-то хочет запускать пользовательские процессы отдельно от системных процессов, есть askubuntu.com/a/859583/457417
Бен
работал отлично набор /proc/sys/kernel/modules_disabledдля 1в конце процесса загрузки
Стюарт Cardall
0

Это действительно зависит от вашего определения «загружен». Я полагаю, вы хотите, чтобы он запускался сразу после запуска getty. Для этого вам нужно добавить свой сервис в /etc/systemd/system/getty.target.wants/каталог. Вы также должны убедиться, что ваш файл использует код, аналогичный другим службам в этом каталоге. Для запуска пользовательского сервиса при загрузке и завершении работы (просто подает звуковой сигнал моей материнской платы), я использую следующий скрипт в/etc/systemd/system/getty.target.wants/service_name.service

[Unit]
After=systemd-user-sessions.service plymouth-quit-wait.service
After=rc-local.service
Before=getty.target
IgnoreOnIsolate=yes

[Service]
ExecStart=/usr/bin/myinitscript.sh start
ExecStop=/usr/bin/myinitscript.sh stop
Type=oneshot
RemainAfterExit=true

[Install]
WantedBy=basic.target

/usr/bin/myinitscript.sh является исполняемым и имеет шебанг в начале.

Обратите внимание, что не все будет запущено в этот момент при загрузке, но это точка, в которой пользователю будет предложено войти в систему.

Хотя это делает использование Before=и After=это было для меня гораздо более понятным и на самом деле работает; Я не нашел вышеуказанный ответ достаточно информативным. Это также позволяет вам использовать и то, ExecStart=и другое ExecStop=, а не ограничиваться Type=simpleподобным сервисом.

Hack5
источник
-2

Я не знаком со спецификой или ArchLinux, но вот как управлять systemd в целом.

Ну, по сути, systemd - это набор скриптов в /etc/init.d/, на которые указывают символические ссылки из /etc/rcX.d, где X - номер уровня выполнения. Сами ссылки имеют следующий формат:

[K | S] + nn + [строка]

где:

  • nn - это число, определяющее порядок выполнения этих скриптов.
  • строка - это имя скрипта в том виде, в каком оно указано в /etc/init.d/
  • и, наконец, K или S определяют команду, с которой вызывается скрипт: stop или start соответственно.

Итак, если вы хотите, чтобы ваш скрипт выполнялся последним в последовательности загрузки, вам нужно сделать следующее:

  1. поместите ваш скрипт в /etc/init.d/ и сделайте его исполняемым
  2. определите целевой уровень запуска, с которого должен начинаться скрипт (обычно 2 для консоли и 5 для графического интерфейса пользователя). Может быть определено с чем-то вродеrunlevel
  3. посмотрите, какие сценарии уже есть на этом уровне выполнения, ls /etc/rc<target runlevel>.d/и выберите двузначное число, которое больше, чем любое другое, уже существующее.
  4. используя утилиту, специфичную для вашего дистрибутива, например, update-rc.dдля Debian, chkconfigдля Fedora или вручную, создайте символическую ссылку /etc/rc.d/S для вашего сценария инициализации.
Павел А
источник
5
То, что вы описали, на самом деле sysVinit. Несмотря на то, что systemd совместим с тем, как работал sysVinit, есть одно ключевое отличие - все выполняется параллельно. Существует также два типа сервисов: сервис sysVinit и сервис systemd. Ваш ответ может помочь выполнению чего-либо после служб sysVinit, но не обязательно системных.
Сэм
1
Systemd не стремится быть совместимым с sysvinit вообще, с самого первого дня.
lzap