Как написать файл systemd .service под управлением systemd-tmpfiles

16

Мне нужно запустить systemd-tmpfiles --createво время процесса загрузки с дистрибутивом systemd. Поэтому мне нужно создать файл systemd .service для этой работы.

В этом вопросе вы можете прочитать все детали о том, что мне нужно и почему: как работает systemd-tmpfiles?

Я прочитал несколько документов об этом, и я пишу следующий тест:

[Unit]
Description=Execute tmpfiles to disable usb-wakeup # see details in the link above
Requires=multi-user.target # see details in the link above
After=multi-user.target    # see details in the link above

[Service]
Type=oneshot
ExecStart=/usr/bin/systemd-tmpfiles --create

[Install]
WantedBy=multi-user.target

Но я не уверен, потому что systemd-tmpfilesэто не простая программа, а часть самого systemd. Я не хотел бы сломать мою систему.

Любые советы о правильном файле .service?

Eang
источник
Проверьте обильную документацию по systemd по адресу freedesktop.org/wiki/Software/systemd . Вы можете изменить настройки системы по умолчанию своими файлами.
vonbrand

Ответы:

30

[Это напрямую не решает проблему systemd-tmpfiles, но я думаю, что вы уже поняли, что в данном конкретном случае вам лучше использовать echo.]

Прежде всего, «multi-user.target» может или не может быть то, что вы хотите использовать. Если вы знакомы с концепцией уровней запуска из материала инициализации в стиле SysV, многопользовательский является системным эквивалентом уровня запуска 3, который представляет собой многопользовательскую систему, которая загружается с консоли, а не с графическим интерфейсом. Эквивалентом уровня запуска 5, который загружается в X, является graphical.target . Значение по умолчанию определяется символической ссылкой в /etc/systemd/system(и / или /lib/systemd/system; эта ссылка /etcотменяет указанную в /lib) с именем default.target , используйте ls, чтобы найти, куда она указывает:

»ls -l /etc/systemd/system/default.target
default.target -> /usr/lib/systemd/system/multi-user.target

Для обычных компьютеров Linux это будет graphical.target. На самом деле это не важно, если вы хотите, чтобы запускаемая вами служба загрузки запускалась независимо от того, какой уровень запуска / целевой уровень по умолчанию - в этом случае мы можем просто использовать default.target и не беспокоиться о том, для чего он является псевдонимом. Однако, если вы используете многопользовательский режим, и по умолчанию используется графический режим, ваш сервис не будет работать.

В зависимости от сервиса, могут быть более подходящие и конкретные цели или сервисы, которые вы хотите запустить по отношению к этому. Исходя из вашего другого вопроса, default.target, вероятно, хорошо. Как примечание, различие между «целью» и «службой» состоит в том, что служба содержит [Service]раздел, который фактически выполняет процесс; цель - это просто способ группировки сервисов с помощью различных директив зависимости и необходимости; он не делает ничего, кроме запуска других целей или услуг.

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

[Unit]
After=default.target

[Install]
WantedBy=default.target

Раздел «Установка» используется при установке службы; «WantedBy» указывает цель, с которой мы хотим, чтобы эта служба была включена (имеется в виду, что она будет работать, если эта цель будет выполняться, но не указывается, когда она будет работать по отношению к другим ). Поскольку мы на самом деле хотим, чтобы эта служба запускалась позже, а не раньше, мы задаем предложение «После». На самом деле это не обязательно должно совпадать с целью WantedBy (обычно это не так) и может быть полностью опущено, если вам все равно, когда это происходит; Я просто использую это как догадку, что большинство других вещей будут запускаться в отношении вещей, которые где-то связаны с тем, что было указано Before=default.target(что мы могли бы также использовать; потребности цели оцениваются до того, как цель будет запущена).

Для примера я просто выведу «hello world» на консоль. Сам сервис описан в [Service]разделе:

[Service]
Type=forking
ExecStart=/usr/local/bin/helloworld

Команде нужен полный путь. Причина, по которой я не просто использовал, /usr/bin/echo "hello world"состоит в том, что она не будет работать (я думаю, что вывод идет в / dev / null), и хотя служба выполняет echo "hello world" > /dev/consoleволю, эксперимент показывает, что использование перенаправления оболочки в директиве ExecStart не будет , Так / USR / местные / бен / HelloWorld это сценарий оболочки с этой одной строки, echo "hello world" > /dev/console.

Обратите внимание на то Type=forking, что необходимо для сценария оболочки.

Наш полный, минимальный файл обслуживание только эти три секции ( [Unit], [Service]и [Install]). Для установки поместите файл или символическую ссылку на него в / etc / systemd / system или / usr / lib / systemd / system, и:

systemctl --system enable helloworld

Это должно напечатать ln -s .... Это не запускает службу, она просто настраивает ее для запуска при загрузке, как обсуждалось выше.

Это в двух словах. man systemd.unitи man systemd.serviceесть больше деталей.

лютик золотистый
источник
1
Спасибо, очень полезный ответ и проблема решена. Просто заметка, в моем дистрибутиве (Chakra Linux) default.targetнет /etc/systemd/system, но только в/usr/lib/systemd/system
eang
Выход из команд регистрируется (куда еще он может идти)?
vonbrand
Файлы / usr / lib / systemd / ... являются резервными (по умолчанию), вы должны
оставить
Эти дни default.targetмогут быть найдены в/lib/systemd/system/default.target
Czerasz
1
@czerasz Я замечаю на Fedora 27, если я systemctl set-default ...оставляю символическую ссылку /etc/systemd/system, но она не меняет одну /lib, т.е. они указывают на разные цели, но вещи в первой должны переопределять последнюю. Если вы установили это самостоятельно, вот что может случиться. Во всяком случае, я редактировал в обоих местах.
Златовласка