Як записати systemd .service файл із запуском systemd-tmpfiles


16

Мені потрібно запустити systemd-tmpfiles --createпід час завантаження процес із системним дистрибутивом. Тому мені потрібно створити файл 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це не проста програма, а сам фрагмент системи. Я не хотів би зламати свою систему.

Якісь поради щодо правильного .service-файлу?


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

Відповіді:


30

[Це безпосередньо не стосується проблеми systemd-tmpfiles, але я думаю, ви вже визнали, що в цьому конкретному випадку вам краще просто використовувати ехо.]

По-перше, "multi-user.target" може бути, а не бути тим, що ви хочете використовувати. Якщо ви знайомі з концепцією пробігу в стилі SysV init речі, багатокористувацький - це системний еквівалент runlevel 3, що є багатокористувацькою системою, яка завантажується на консоль, а не GUI. Еквівалент runlevel 5, який завантажується в X, є graphic.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" вказує ціль, з якою ми хочемо включити цю послугу (це означає, що вона буде запущена, якщо така ціль є, але nb. Це не визначає, коли вона запускатиметься стосовно інших ). Оскільки ми насправді хочемо, щоб ця послуга запускалася пізніше, ніж швидше, тоді ми визначаємо пункт "Після". Це насправді не повинно бути таким же, як ціль WantedBy (зазвичай це не так) і може бути повністю опущено, якщо вам не байдуже, коли це станеться; Я просто використовую це на думку про те, що більшість інших матеріалів буде запущено стосовно речей, які десь приковані до чогось визначеного Before=default.target(що ми також могли б використати; бажання цілі оцінюються до запуску цілі).

Для прикладу я просто відлуню "привіт світ" до консолі. Сама послуга описана в [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

Вихід з команд записується в журнал (куди ще він міг би піти)?
фонбранд

Файли / usr / lib / systemd / ... запасні (за замовчуванням), ви повинні залишити свої в / etc / systemd / ...
vonbrand

Ці дні default.targetможна знайти у/lib/systemd/system/default.target
czerasz

1
@czerasz Я помічаю на Fedora 27, якщо я залишаю systemctl set-default ...символьне посилання /etc/systemd/system, але це не змінює значення в одному /lib, тобто вони вказують на різні цілі, але речі в першому повинні переважати останні. Якщо ви самі це встановили, це може статися. У будь-якому випадку я редагував в обох місцях.
золотинки

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.