Як запустити скрипт із systemd безпосередньо перед відключенням?


58

Що потрібно помістити в [install]розділ, щоб системний запуск працював /home/me/so.plбезпосередньо перед вимкненням, а також перед тим, як /proc/self/net/devйого знищити?

[Unit]
Description=Log Traffic

[Service]
ExecStart=/home/me/so.pl

[Install]
?

Відповіді:


66

Пропоноване рішення - запустити сервісний блок як звичайний сервіс - ознайомтеся з [Install]розділом. Тож все треба думати зворотно, залежності теж. Тому що порядок відключення - це зворотний порядок запуску. Ось чому сценарій повинен бути розміщений ExecStop=.

Наступне рішення працює для мене:

[Unit]
Description=...

[Service]
Type=oneshot
RemainAfterExit=true
ExecStop=<your script/program>

[Install]
WantedBy=multi-user.target

RemainAfterExit=trueпотрібен, коли у вас немає ExecStartдії.

Після створення файлу переконайтесь, що systemctl daemon-reloadі systemctl enable yourservice --now.

Я щойно отримав це від систематизованого IRC, кредити йдуть на mezcalero.


6
В ubuntu 16.04 ви повинні мати ExecStart=/bin/true.
niels

3
Моє припущення ЧОМУ RemainAfterExit=true потрібне, коли немає ExecStart, тому що systemdне буде намагатися запустити, ExecStopякщо він вважає, що послуга не працює. RemainAfterExit=trueпризводить systemdдо вважаю , що служба працює, тим самим змушуючи його працювати ExecStopпри виключенні.
Феліпе Альварес

1
Чи все-таки потрібно забезпечити запуск цього сценарію та завершення до завершення сеансів роботи користувачів та користувацьких процесів?
richmb

@richmb Не зовсім. Із Документів :Note that it is usually not sufficient to specify a command for this setting that only asks the service to terminate (for example, by queuing some form of termination signal for it), but does not wait for it to do so.
svenwltr

Я спробував це і різні ітерації на ньому, але це не працює на Debian Stretch.
2rs2ts

8

Наскільки я бачу, це робить те, що мені потрібно (але я не знаю точно чому).

[Unit]
Description=Log Traffic
DefaultDependencies=no
Before=shutdown.target reboot.target halt.target


[Service]
ExecStart=/usr/local/bin/perl /home/me/log_traffic.pl --stop
Type=oneshot

3
Це трапляється через 2 речі: 1) DefaultDependitions = no змушує ігнорувати всі залежності та виконувати "спочатку" на початку та "нарешті" на зупинці, завжди дотримуючись пунктів "До" та "Після". 2) У міркуванні "shutdown / reboot / halt" є пункт "Перед", тому він запуститься безпосередньо перед тим, як зупинка / перезавантаження / зупинка буде досягнута на зупинці (тому що вони працюють лише при зупинці, це відбувається, щоб зробити те, що ви хочете).
RDP

Можливо, ви захочете додати kexec.targetдо "Біт"
hanetzer"

Це не працює для мене
Bug Killer

Я не бачу, як це буде працювати, якщо ви також не додасте WantedBy=shutdown.target reboot.target halt.targetдо [Unit]розділу. Before=& After=не змінювати залежності.
rsaw

1
@FelipeAlvarez: Я видалив свій коментар.
sid_com

7
  • Щоб запустити службу безпосередньо перед запуском будь-якої служби перезавантаження / вимкнення / зупинки / kexec (тобто в останній момент, перш ніж коренева файлова система перераховується лише для читання), використовуйте цю конфігурацію служби:

    [Unit]
    Description=Save system clock on shutdown
    DefaultDependencies=no
    After=final.target
    
    [Service]
    Type=oneshot
    ExecStart=/usr/lib/systemd/scripts/fake-hwclock.sh save
    
    [Install]
    WantedBy=final.target
    

    Увімкніть це за допомогою:

    systemctl enable my_service.service
    
  • Щоб запустити скрипт безпосередньо перед перезавантаженням / вимкненням / halt / kexec (коли ви не можете записати в кореневу файлову систему, тому що вона була перероблена лише для читання), додайте цей виконуваний сценарій до /usr/lib/systemd/system-shutdownкаталогу.

    Безпосередньо перед виконанням фактичної зупинки системи / poweroff / reboot / kexec systemd-shutdown запустить усі виконувані файли в / usr / lib / systemd / system-shutdown / і передасть їм один аргумент: або "halt", "poweroff", "reboot "або" kexec ", залежно від обраної дії. Всі виконувані файли в цьому каталозі виконуються паралельно, і виконання дії не продовжується до того, як всі виконувані файли закінчені.

Також дивіться:

https://www.freedesktop.org/software/systemd/man/bootup.html

https://www.freedesktop.org/software/systemd/man/systemd-halt.service.html


1
Я хочу виконати щось якомога ближче після ініціювання перезавантаження, перед тим як final.target. В ідеалі я хотів би, щоб це перше, що виконується після того, як це зробити користувач $ sudo reboot.
Хайме Хаблуцель

5

Я не зовсім впевнений, але я не думаю, що вам потрібна частина встановлення, хоча я явно додав її. Я також не перевіряв його, але я думаю, що це повинно допомогти вам почати:

[Unit]
Description=Log Traffic
Requires=network.target
After=network.target
Before=shutdown.target
DefaultDependencies=no

[Service]
ExecStart=/home/me/so.pl
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=shutdown.target

Коли я спробую це, сценарій виконується незабаром після запуску (завантаження).
sid_com

@sid_com Після прочитання теми.gmane.org/gmane.comp.sysutils.systemd.devel/4515/… спробуйте додати DefaultDependitions = ні і, можливо, видаліть розділ встановлення. В іншому випадку це може допомогти видалити лінії після / потрібні.
Ульріх Дангель
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.