Jak uruchomić skrypt z systemd tuż przed zamknięciem?


58

Co muszę umieścić w tej [install]sekcji, aby systemd działał /home/me/so.pltuż przed wyłączeniem, a także przed /proc/self/net/devzniszczeniem?

[Unit]
Description=Log Traffic

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

[Install]
?

Odpowiedzi:


66

Sugerowanym rozwiązaniem jest uruchomienie jednostki serwisowej jako normalnej usługi - spójrz na [Install]sekcję. Więc wszystko musi być odwrócone, również zależności. Ponieważ kolejność zamykania jest odwrotną kolejnością uruchamiania. Dlatego skrypt musi zostać umieszczony ExecStop=.

Działa dla mnie następujące rozwiązanie:

[Unit]
Description=...

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

[Install]
WantedBy=multi-user.target

RemainAfterExit=truejest potrzebny, gdy nie masz ExecStartakcji.

Po utworzeniu pliku upewnij się, że systemctl daemon-reloadi systemctl enable yourservice --now.

Właśnie dostałem to z systemd IRC, kredyty trafią do mezcalero.


6
W Ubuntu 16.04 musisz mieć ExecStart=/bin/true.
niels

3
Moje przypuszczenie do DLACZEGO RemainAfterExit=true jest wymagane, gdy go nie ma, ExecStartponieważ systemdnie podejmie próby uruchomienia, ExecStopjeśli uzna, że ​​usługa nie działa. RemainAfterExit=truePowoduje systemd, aby wierzyć , że usługa działa, powodując w ten sposób go uruchomić ExecStopprzy wyłączaniu.
Felipe Alvarez

1
Czy istnieje sposób, aby skrypt ten został uruchomiony i zakończony przed zakończeniem sesji użytkownika i procesów użytkownika?
richmb,

@richmb Wcale nie. Z dokumentów :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

Próbowałem tego i różnych iteracji, ale nie działa na Debian Stretch.
2rs2ts

8

O ile widzę, robi to, czego potrzebuję (ale nie wiem dokładnie, dlaczego).

[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
Dzieje się tak z powodu 2 rzeczy: 1) DefaultDependencies = no powoduje, że ignoruje wszystkie zależności i uruchamia się „na początku” na starcie i „nareszcie” na stopie, zawsze przestrzegając klauzul „Przed” i „Po”. 2) Zdarza się, że ma klauzulę Before dotyczącą celów zamknięcia / ponownego uruchomienia / zatrzymania, więc będzie działać tuż przed zamknięciem / ponownym uruchomieniem / zatrzymaniem przy zatrzymaniu (ponieważ uruchamiają się tylko przy zatrzymaniu, zdarza się, aby zrobić to, co chcesz).
PROW

Możesz dodać kexec.targetdo bitu Przed
hanetzer

To nie działa dla mnie
Bug Killer

Nie widzę, jak to będzie działać, chyba że dodasz również WantedBy=shutdown.target reboot.target halt.targetdo [Unit]sekcji. Before=i After=nie zmieniaj zależności.
rsaw

1
@FelipeAlvarez: Usunąłem swój komentarz.
sid_com

7
  • Aby uruchomić usługę tuż przed uruchomieniem jakichkolwiek usług ponownego uruchamiania / zamykania / zatrzymania / kexec (tj. W ostatnim momencie przed ponownym zamontowaniem głównego systemu plików tylko do odczytu) skorzystaj z tej konfiguracji usługi:

    [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
    

    Włącz to za pomocą:

    systemctl enable my_service.service
    
  • Aby uruchomić skrypt bezpośrednio przed ponownym uruchomieniem / zamknięciem / zatrzymaniem / kexec (gdy nie można zapisać do głównego systemu plików, ponieważ został on ponownie zamontowany tylko do odczytu), dodaj ten skrypt do /usr/lib/systemd/system-shutdownkatalogu.

    Bezpośrednio przed wykonaniem rzeczywistego zatrzymania systemu / poweroff / restartu / kexec systemd-shutdown uruchomi wszystkie pliki wykonywalne w / usr / lib / systemd / system-shutdown / i przekaże im jeden argument: „halt”, „poweroff”, „restart ”lub„ kexec ”, w zależności od wybranej akcji. Wszystkie pliki wykonywalne w tym katalogu są wykonywane równolegle, a wykonywanie akcji nie jest kontynuowane przed zakończeniem wszystkich plików wykonywalnych.

Zobacz także:

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

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


1
Chcę wykonać coś tak blisko, jak to możliwe po zainicjowaniu ponownego uruchomienia komputera, na długo przed final.target. Idealnie chciałbym, aby była to pierwsza rzecz wykonywana po wykonaniu przez użytkownika $ sudo reboot.
Jaime Hablutzel

5

Nie jestem do końca pewien, ale nie sądzę, że potrzebujesz części instalacyjnej, ale dodałem ją wyraźnie. Ja również tego nie przetestowałem, ale myślę, że powinno ci to pomóc:

[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

Kiedy próbuję, skrypt jest uruchamiany wkrótce po starcie (boot).
sid_com

@sid_com Po przeczytaniu thread.gmane.org/gmane.comp.sysutils.systemd.devel/4515/… spróbuj dodać DefaultDependencies = nie i może usunąć sekcję instalacji. W przeciwnym razie może pomóc zdalnie sterować wierszami następującymi / wymagającymi.
Ulrich Dangel
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.