Come eseguire uno script con systemd subito prima dell'arresto?


58

Cosa devo inserire nella [install]sezione, in modo che systemd venga eseguito /home/me/so.plprima dell'arresto e anche prima che /proc/self/net/devvenga distrutto?

[Unit]
Description=Log Traffic

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

[Install]
?

Risposte:


66

La soluzione suggerita è quella di eseguire l'unità di servizio come un normale servizio - dai un'occhiata alla [Install]sezione. Quindi tutto deve essere pensato al contrario, anche le dipendenze. Perché l'ordine di spegnimento è l'ordine di avvio inverso. Ecco perché lo script deve essere inserito ExecStop=.

La seguente soluzione funziona per me:

[Unit]
Description=...

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

[Install]
WantedBy=multi-user.target

RemainAfterExit=trueè necessario quando non hai ExecStartun'azione.

Dopo aver creato il file, assicurarsi di systemctl daemon-reloade systemctl enable yourservice --now.

L'ho appena ricevuto dall'IRC di sistema, i crediti vanno a mezcalero.


6
A Ubuntu 16.04 devi avere un ExecStart=/bin/true.
Niels

3
La mia ipotesi su PERCHÉ RemainAfterExit=true è richiesta quando non ce n'è ExecStartperché systemdnon tenterà di funzionare ExecStopse ritiene che il servizio non sia in esecuzione. RemainAfterExit=trueprovoca systemda credere che il servizio è in esecuzione, provocando l'esecuzione ExecStopallo spegnimento.
Felipe Alvarez,

1
Esiste un modo per garantire che questo script venga eseguito e completato prima che le sessioni utente e i processi utente vengano interrotti?
richmb,

@richmb Niente affatto. Dai documenti :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,

Ho provato questo e varie iterazioni su di esso ma non funziona su Debian Stretch.
2rs2ts

8

Per quanto posso vedere, fa quello che mi serve (ma non so esattamente perché).

[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
Succede a causa di 2 cose: 1) DefaultDependencies = no rende ignora tutte le dipendenze ed esegue "all'inizio" all'avvio e "alla fine" all'arresto, rispettando sempre le clausole "Prima" e "Dopo". 2) Capita di avere una clausola Prima sugli obiettivi di arresto / riavvio / arresto, quindi verrà eseguita appena prima che l'arresto / riavvio / arresto venga raggiunto all'arresto (perché funzionano solo all'arresto, fa quello che vuoi).
PSR

Potresti voler aggiungere kexec.targetal bit Before
hanetzer il

Questo non funziona per me
Bug Killer

Non vedo come funzionerà a meno che non si aggiunga anche WantedBy=shutdown.target reboot.target halt.targetalla [Unit]sezione. Before=e After=non cambiare le dipendenze.
RS

1
@FelipeAlvarez: ho rimosso il mio commento.
sid_com,

7
  • Per eseguire un servizio subito prima di avviare uno dei servizi reboot / shutdown / halt / kexec (cioè nell'ultimo momento prima che il filesystem di root venga rimontato in sola lettura) usa questo servizio config:

    [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
    

    Abilitalo con:

    systemctl enable my_service.service
    
  • Per eseguire uno script subito prima del vero riavvio / shutdown / halt / kexec (quando non è possibile scrivere sul filesystem di root, perché è stato rimontato in sola lettura) aggiungere questo script eseguibile alla /usr/lib/systemd/system-shutdowndirectory.

    Immediatamente prima di eseguire l'arresto di sistema reale / poweroff / reboot / kexec systemd-shutdown eseguirà tutti gli eseguibili in / usr / lib / systemd / system-shutdown / e passerà loro un argomento: "halt", "poweroff", "reboot "o" kexec ", a seconda dell'azione scelta. Tutti gli eseguibili in questa directory vengono eseguiti in parallelo e l'esecuzione dell'azione non viene continuata prima del completamento di tutti gli eseguibili.

Vedi anche:

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

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


1
Voglio eseguire qualcosa il più vicino possibile dopo aver avviato un riavvio, molto prima di final.target. Idealmente, vorrei che fosse la prima cosa che viene eseguita dopo l'utente $ sudo reboot.
Jaime Hablutzel,

5

Non ne sono del tutto sicuro, ma non penso che tu abbia bisogno della parte di installazione sebbene l'ho aggiunta esplicitamente. Inoltre non l'ho provato ma penso che dovrebbe aiutarti a iniziare:

[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

Quando provo questo, lo script viene eseguito subito dopo l'avvio (avvio).
sid_com,

@sid_com Dopo aver letto thread.gmane.org/gmane.comp.sysutils.systemd.devel/4515/… prova ad aggiungere DefaultDependencies = no e forse rimuovere la sezione di installazione. Altrimenti può aiutare a remotare le linee after / richiede.
Ulrich Dangel,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.