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


58

Что мне нужно поместить в [install]раздел, чтобы systemd работал /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.

Я только что получил это от systemd IRC, кредиты идут в mezcalero.


6
В Ubuntu 16.04 вы должны иметь ExecStart=/bin/true.
Нильс

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) DefaultDependencies = no заставляет игнорировать все зависимости и запускать «сначала» при запуске и «наконец» при остановке, всегда соблюдая условия «До» и «После». 2) У него есть предложение Before для целей shutdown / reboot / halt, поэтому он будет работать непосредственно перед достижением 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
  • Чтобы запустить службу прямо перед запуском любой из служб reboot / shutdown / halt / 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
    
  • Чтобы запустить скрипт непосредственно перед фактической перезагрузкой / shutdown / 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 После прочтения thread.gmane.org/gmane.comp.sysutils.systemd.devel/4515/… попробуйте добавить DefaultDependencies = no и, возможно, удалить раздел установки. В противном случае это может помочь удалить строки после / требующие.
Ульрих Дангел
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.