Comment écrire un file systemd .service exécutant systemd-tmpfiles

J'ai besoin d'exécuter systemd-tmpfiles --create pendant le process de démarrage avec une dissortingbution systemd. J'ai donc besoin de créer un file systemd .service faisant ce travail.

Dans cette question, vous pouvez lire tous les détails sur ce dont j'ai besoin et pourquoi: Comment fonctionne systemd-tmpfiles?

J'ai lu quelques documents à ce sujet et j'écris le test suivant:

 [Unit] Description=Execute tmpfiles to disable usb-wakeup # see details in the link above Requires=multi-user.target # see details in the link above After=multi-user.target # see details in the link above [Service] Type=oneshot ExecStart=/usr/bin/systemd-tmpfiles --create [Install] WantedBy=multi-user.target 

Mais je ne suis pas sûr, car systemd-tmpfiles n'est pas un programme simple mais un morceau de systemd lui-même. Je ne voudrais pas briser mon système.

Des conseils sur un file .service correct?

[Cela n'aborde pas directement la question de systemd-tmpfiles mais je pense que vous avez déjà reconnu que dans ce cas particulier, il vaut mieux utiliser simplement echo.]

Tout d'abord, "multi-user.target" peut être ou ne pas être ce que vous voulez utiliser. Si vous êtes familier avec le concept de runlevels à partir de trucs de style SysV, multi-user est l'équivalent systeme de runlevel 3, qui est un système multi-user qui démarre sur une console et non sur une interface graphique. L'équivalent de runlevel 5, qui démarre sur X, est graphical.target . La valeur par défaut est déterminée par un lien symbolique dans le file / etc / systemd / system appelé default.target , utilisez ls pour find où il pointe:

 »ls -l /etc/systemd/system/default.target default.target -> /usr/lib/systemd/system/multi-user.target 

Pour les ordinateurs de bureau Linux normaux, ce sera graphique.target. Cela n'est pas important si vous voulez que le service de démarrage que vous créez commence quel que soit le niveau d'exécution / cible par défaut. Dans ce cas, nous utiliserons default.target et nous ne nous soucierons pas de son alias. Cependant, si vous utilisez plusieurs users et que votre valeur par défaut est graphique, votre service n'aura pas lieu.

Selon le service, il peut y avoir des cibles ou des services plus appropriés et spécifiques que vous voulez commencer celui-ci par rapport à. Basé sur votre autre question, default.target est probablement bien. En note, la différence entre une «cible» et un «service» est qu'un service contient une section [Service] qui exécute un process; une cible est juste un moyen de regrouper les services set via les différentes directives «dépend» et «nécessite»; il ne fait rien de son propre au-delà de triggersr d'autres cibles ou services.

Lorsqu'un service démarre, il est déterminé par les autres services qui en dépendent explicitement. Dans le cas d'un événement simple et autonome comme celui-ci que nous voulons exécuter en retard dans le process de démarrage, nous pouvons utiliser cette combinaison de directives:

 [Unit] After=default.target [Install] WantedBy=default.target 

La section "Installer" est utilisée lorsque le service est installé; "WantedBy" spécifie une cible avec laquelle ce service doit être inclus (ce qui signifie qu'il s'exécutera si cette cible le fait, mais cela ne détermine pas quand il sera exécuté par rapport aux autres ). Puisque nous voulons réellement que ce service s'exécute plus tard plutôt que plus tôt, nous spécifions ensuite une clause "After". Cela n'a pas besoin d'être identique à la cible WantedBy (ce n'est généralement pas le cas) et peut être complètement omis si vous ne vous en souciez pas quand cela arrive; Je l'utilise juste sur le fait que la plupart des autres choses seront exécutées par rapport à quelque chose qui est enchaîné à quelque chose qui a spécifié Before=default.target (que nous aurions aussi pu utiliser, les besoins d'une cible sont évalués avant la cible est exécuté).

Pour l'exemple, je vais juste faire écho "Bonjour tout le monde" à la console. Le service lui-même est décrit dans la section [Service] :

 [Service] Type=forking ExecStart=/usr/local/bin/helloworld 

La command a besoin d'un path complet. La raison pour laquelle je n'ai pas utilisé /usr/bin/echo "hello world" est que ça ne marchera pas (la sortie va à / dev / null, je pense), et alors qu'un service qui fait un echo "hello world" > /dev/console , l'expérimentation démontre que l'utilisation de la redirection de shell dans une directive ExecStart ne le sera pas. So / usr / local / bin / helloworld est un script shell avec cette seule ligne, echo "hello world" > /dev/console .

Notez le Type=forking , qui est nécessaire pour un script shell.

Notre file de service complet et minimal est constitué de trois sections ( [Unit] , [Service] et [Install] ). Pour l'installer, placez le file ou un lien symbolique dans / etc / systemd / system ou / usr / lib / systemd / system et:

 systemctl --system enable helloworld 

Il devrait imprimer ln -s ... Cela n'exécute pas le service, il le configure juste pour s'exécuter au démarrage comme discuté ci-dessus.

C'est en un mot. man systemd.unit et man systemd.service ont plus de détails.

Pour le service systemd-tmpfiles: il doit être livré avec votre dissortingbution, mais vous pouvez toujours récupérer le file de service depuis le repository amont git