42 votes

Comment faire d'un service systemd le dernier service au démarrage ?

Il y a de nombreuses années, nous pouvions écrire notre script de démarrage dans /etc/rc.local. Après le chargement de tous les services système, votre script s'exécutera.

Maintenant, nous utilisons systemd, nous n'avons plus de rc.local. Systemd démarre le service en parallèle. Vous pouvez écrire votre propre service pour agir comme rc.local, mais vous ne pouvez pas être sûr qu'il s'exécutera après le chargement de tous les services système.

Existe-t-il un moyen de le faire? Ou devons-nous utiliser Before et After dans le fichier de service systemd?

37voto

Dans systemd, il est conseillé d'utiliser Before= et After= pour ordonner vos services de manière agréable parmi les autres.

Mais comme vous avez demandé une façon de le faire sans utiliser Before et After, vous pouvez utiliser :

Type=idle

ce qui comme le man systemd.service explique :

Le comportement de idle est très similaire à simple; cependant, l'exécution réelle du programme de service est retardée jusqu'à ce que tous les travaux actifs soient traités. Cela peut être utilisé pour éviter la superposition de la sortie des services shell avec la sortie d'état sur la console. Notez que ce type est uniquement utile pour améliorer la sortie de la console, il n'est pas utile comme outil général d'ordonnancement des unités et l'effet de ce type de service est soumis à un délai de 5 secondes, après quoi le programme de service est invoqué de toute façon.

3voto

Hack5 Points 151

Cela dépend vraiment de votre définition de "booted". Je suppose que vous voulez qu'il s'exécute immédiatement après le démarrage de getty. Pour ce faire, vous devez ajouter votre service au répertoire /etc/systemd/system/getty.target.wants/. Vous devez également vous assurer que votre fichier utilise un code similaire aux autres services de ce répertoire. Pour exécuter un service personnalisé au démarrage et à l'arrêt (qui fait simplement sonner le buzzer de ma carte mère), j'utilise le script suivant dans /etc/systemd/system/getty.target.wants/service_name.service

[Unit]
After=systemd-user-sessions.service plymouth-quit-wait.service
After=rc-local.service
Before=getty.target
IgnoreOnIsolate=yes

[Service]
ExecStart=/usr/bin/myinitscript.sh start
ExecStop=/usr/bin/myinitscript.sh stop
Type=oneshot
RemainAfterExit=true

[Install]
WantedBy=basic.target

/usr/bin/myinitscript.sh est exécutable et a un shebang au début.

Notez que tout ne sera pas démarré à ce moment du démarrage, mais c'est à ce moment-là que le prompt de connexion apparaît à l'utilisateur

Même si cela utilise Before= et After=, c'était pour moi beaucoup plus compréhensible et cela fonctionne effectivement ; je n'ai pas trouvé la réponse ci-dessus assez informative. Cela vous permet également d'utiliser à la fois ExecStart= et ExecStop=, plutôt que d'être limité à un service de type Type=simple.

3voto

MCO System Points 131

La meilleure façon de s'assurer que notre service s'exécute après tous les autres services activés est de créer votre propre cible et de la faire fonctionner après multi-user.target.

Généralement :

  1. Créez un fichier d'unité cible /etc/systemd/system/custom.target avec AllowIsolate=yes

    [Unit] Description=Ma cible personnalisée Requires=multi-user.target After=multi-user.target AllowIsolate=yes

  2. Créez votre fichier d'unité de service /etc/systemd/system/last_command.service avec After=multi-user.target et WantedBy=custom.target

    [Unit] Description=Ma commande personnalisée After=multi-user.target

    [Service] Type=simple ExecStart=/usr/local/bin/my_last_command.sh

    [Install] WantedBy=custom.target

  3. Créez le répertoire /etc/systemd/system/custom.target.wants

  4. Reliez votre service last_command.service dans /etc/systemd/system/custom.target.wants

    ln -s /etc/systemd/system/last_command.service \ /etc/systemd/system/custom.target.wants/last_command.service

  5. Rechargez systemd avec systemctl daemon-reload

  6. Définissez la cible par défaut du système comme custom.target

    systemctl set-default custom.target

  7. Optionnellement, vous pouvez vouloir appliquer immédiatement la custom.target

    systemctl isolate custom.target

De cette manière, à chaque redémarrage, votre dernière commande sera exécutée après l'atteinte de la cible multi-user.target.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X