Comment exécuter un script avec systemd juste avant l’arrêt?

58

Que dois-je mettre dans la [install]section, de sorte que systemd s'exécute /home/me/so.pljuste avant l'arrêt et avant d' /proc/self/net/devêtre détruit?

[Unit]
Description=Log Traffic

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

[Install]
?
sid_com
la source

Réponses:

66

La solution suggérée est de faire fonctionner l'unité de service comme un service normal - consultez la [Install]section. Donc tout doit être pensé en sens inverse, les dépendances aussi. Parce que l'ordre d'arrêt est l'ordre de démarrage inverse. C'est pourquoi le script doit être placé dans ExecStop=.

La solution suivante fonctionne pour moi:

[Unit]
Description=...

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

[Install]
WantedBy=multi-user.target

RemainAfterExit=trueest nécessaire lorsque vous n'avez pas d' ExecStartaction.

Après avoir créé le fichier, assurez-vous de systemctl daemon-reloadet systemctl enable yourservice --now.

Je viens de le recevoir de systemd IRC, les crédits vont à mezcalero.

Matthias
la source
6
À Ubuntu 16.04, vous devez avoir un ExecStart=/bin/true.
Niels
3
Mon hypothèse de WHY RemainAfterExit=true est requise quand il n'y en a pas ExecStartcar systemdelle ne tentera pas de s'exécuter ExecStopsi elle pense que le service n'est pas en cours d'exécution. RemainAfterExit=truecause systemdà croire que le service est en cours d' exécution, ce qui provoque son exécution ExecStopà l' arrêt.
Felipe Alvarez
1
Est-il possible de s'assurer que ce script sera exécuté et terminé avant que les sessions et les processus utilisateur ne soient terminés?
richmb
@richmb Pas du tout. De la documentation :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
J'ai essayé ceci et diverses itérations dessus, mais cela ne fonctionne pas sous Debian Stretch.
2rs2ts
8

Autant que je sache, c'est ce dont j'ai besoin (mais je ne sais pas exactement pourquoi).

[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
sid_com
la source
3
Cela fonctionne pour deux raisons: 1) DefaultDependencies = no fait qu'il ignore toutes les dépendances et exécute "au premier" au démarrage et "au dernier" à l'arrêt, en respectant toujours les clauses "Avant" et "Après". 2) Il y a une clause Before sur les cibles shutdown / reboot / stop, afin qu'elle s'exécute juste avant l'arrêt / redémarrage / arrêt à l'arrêt (car elles ne fonctionnent qu'à l'arrêt, il fait ce que vous voulez).
RDP
Vous voudrez peut-être ajouter kexec.targetau bit Avant
hanetzer
Cela ne fonctionne pas pour moi
Bug Killer
Je ne vois pas comment cela fonctionnera à moins que vous ajoutiez également WantedBy=shutdown.target reboot.target halt.targetà la [Unit]section. Before=& After=ne changez pas les dépendances.
réveillé le
1
@ FelipeAlvarez: J'ai supprimé mon commentaire.
sid_com
7
  • Pour exécuter un service juste avant de démarrer l’ un des services de redémarrage / arrêt / arrêt / kexec (c’est-à-dire au dernier moment avant que le système de fichiers racine ne soit remonté en lecture seule), utilisez cette configuration de service:

    [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
    

    Activez-le avec:

    systemctl enable my_service.service
    
  • Pour exécuter un script juste avant le redémarrage / shutdown / halt / kexec (lorsque vous ne pouvez pas écrire sur le système de fichiers racine car il a été remonté en lecture seule), ajoutez ce fichier exécutable dans le /usr/lib/systemd/system-shutdownrépertoire.

    Immédiatement avant d'exécuter le système actuel stop / poweroff / reboot / kexec, systemd-shutdown exécutera tous les exécutables dans / usr / lib / systemd / system-shutdown / et leur transmettra un argument: soit "halt", "poweroff", "reboot", "ou" kexec ", en fonction de l'action choisie. Tous les exécutables de ce répertoire sont exécutés en parallèle et l'exécution de l'action n'est pas poursuivie avant la fin de tous les exécutables.

Regarde aussi:

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

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

Piotr Jurkiewicz
la source
1
Je veux exécuter quelque chose d'aussi près que possible après avoir lancé un redémarrage, bien avant le final.target. Idéalement, j'aimerais que ce soit la première chose à exécuter après l'utilisateur $ sudo reboot.
Jaime Hablutzel
5

Je ne suis pas tout à fait sûr mais je ne pense pas que vous ayez besoin de la partie installation même si je l'ai ajoutée explicitement. Je ne l'ai pas non plus testé, mais je pense que cela devrait vous aider à démarrer:

[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
Ulrich Dangel
la source
Lorsque j'essaie, le script est exécuté peu de temps après le démarrage (démarrage).
sid_com
@sid_com Après avoir lu thread.gmane.org/gmane.comp.sysutils.systemd.devel/4515/…, essayez d'ajouter DefaultDependencies = no et supprimez peut-être la section d'installation. Sinon, il peut être utile d’éloigner les lignes after / needs.
Ulrich Dangel