Wie kann ich systemd-Dienste überschreiben oder konfigurieren?

109

Viele Sysv-Init-Skripte verwendeten eine entsprechende Datei in /etc/default, damit der Administrator sie konfigurieren konnte. Startaufträge können mithilfe von .overrideDateien geändert werden . Wie kann ich systemd-Einheiten überschreiben oder konfigurieren, jetzt wo systemd der Standard in Ubuntu ist?

muru
quelle
Beachten Sie, dass Sie beim Löschen des ExecStart=mit einem leeren Eintrag versehenen Eintrags keinen Kommentar hinterlassen können, der wie ExecStart= # Empty line to clear previous entries.folgt lautet: Dies wird als ein anderer ExecStart=Eintrag übernommen und der Liste hinzugefügt. PS. Ich konnte murus Antwort wegen meines schlechten Rufs nicht kommentieren.
Tysik

Antworten:

185

systemdEinheiten müssen Dateien in nicht befolgen /etc/default. systemdist leicht konfigurierbar, setzt jedoch voraus, dass Sie die Syntax der systemd-Unit-Dateien kennen.

Pakete versenden Einheitendateien normalerweise in /lib/systemd/system/. Diese dürfen nicht bearbeitet werden. systemdErmöglicht Ihnen stattdessen, diese Dateien zu überschreiben, indem Sie entsprechende Dateien in erstellen /etc/systemd/system/.

Für einen bestimmten Service foowürde das Paket bieten /lib/systemd/system/foo.service. Sie können den Status mit überprüfen systemctl status foooder die Protokolle mit anzeigen journalctl -u foo. Um etwas in der Definition von zu überschreiben foo, mache:

sudo systemctl edit foo

Dadurch wird ein Verzeichnis erstellt, /etc/systemd/systemdas nach dem Gerät benannt ist, und eine override.confDatei in diesem Verzeichnis ( /etc/systemd/system/foo.service.d/override.conf). Mit dieser Datei (oder anderen .confDateien in /etc/systemd/system/foo.service.d/) können Sie Einstellungen hinzufügen oder überschreiben .

Befehlsargumente überschreiben

Nehmen Sie gettyzum Beispiel den Service. Angenommen, ich möchte, dass mein Benutzer TTY2 automatisch anmeldet (dies ist nicht ratsam, sondern nur ein Beispiel). TTY2 wird vom getty@tty2Dienst ausgeführt ( tty2wobei es sich um eine Instanz der Vorlage handelt /lib/systemd/system/getty@service). Dazu muss ich den getty@tty2Dienst anpassen .

$ systemctl cat getty@tty2
# /lib/systemd/system/[email protected]
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Getty on %I
Documentation=man:agetty(8) man:systemd-getty-generator(8)
Documentation=http://0pointer.de/blog/projects/serial-console.html
After=systemd-user-sessions.service plymouth-quit-wait.service
After=rc-local.service

# If additional gettys are spawned during boot then we should make
# sure that this is synchronized before getty.target, even though
# getty.target didn't actually pull it in.
Before=getty.target
IgnoreOnIsolate=yes

# On systems without virtual consoles, don't start any getty. Note
# that serial gettys are covered by [email protected], not this
# unit.
ConditionPathExists=/dev/tty0

[Service]
# the VT is cleared by TTYVTDisallocate
ExecStart=-/sbin/agetty --noclear %I $TERM
Type=idle
Restart=always
RestartSec=0
UtmpIdentifier=%I
TTYPath=/dev/%I
TTYReset=yes
TTYVHangup=yes
TTYVTDisallocate=yes
KillMode=process
IgnoreSIGPIPE=no
SendSIGHUP=yes

# Unset locale for the console getty since the console has problems
# displaying some internationalized messages.
Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION=

[Install]
WantedBy=getty.target
DefaultInstance=tty1

Insbesondere muss ich die ExecStartZeile ändern , die derzeit ist:

$ systemctl cat getty@tty2 | grep Exec     
ExecStart=-/sbin/agetty --noclear %I $TERM

Um dies zu überschreiben, gehen Sie wie folgt vor:

sudo systemctl edit getty@tty2

Und füge hinzu:

[Service]
ExecStart=
ExecStart=-/sbin/agetty -a muru --noclear %I $TERM

Beachten Sie, dass:

  1. Ich musste ausdrücklich klar , ExecStartbevor sie wieder einstellen, da es eine additive Einstellung ist ähnlich After, Environment(als Ganze, nicht pro-Variable) und EnvironmentFile, und im Gegensatz zu überschreiben Einstellungen , wie RestartSecoder Type. ExecStartkann nur für Type=oneshotDienste mehrere Einträge enthalten .
  2. Ich musste die richtige Abschnittsüberschrift verwenden. Befindet sich in der Originaldatei ExecStartin der [Service]Sektion, so muss mein Override auch ExecStartin der [Service]Sektion stehen. Wenn Sie sich die eigentliche Servicedatei mit ansehen, systemctl caterfahren Sie oft, was Sie überschreiben müssen und in welchem ​​Bereich sie sich befindet.

Wenn Sie eine systemd-Unit-Datei bearbeiten, müssen Sie normalerweise Folgendes ausführen, damit sie wirksam wird:

sudo systemctl daemon-reload

systemctl editTut dies jedoch automatisch für Sie.

Jetzt:

$ systemctl cat getty@tty2 | grep Exec
ExecStart=-/sbin/agetty --noclear %I $TERM
ExecStart=
ExecStart=-/sbin/agetty -a muru --noclear %I $TERM

$ systemctl show getty@tty2 | grep ExecS
ExecStart={ path=/sbin/agetty ; argv[]=/sbin/agetty -a muru --noclear %I $TERM ; ... }

Und wenn doch:

sudo systemctl restart getty@tty2

und drücken Sie CtrlAltF2, presto! Ich werde auf diesem TTY in meinem Konto angemeldet sein.

Wie ich schon sagte, getty@tty2ist eine Instanz einer Vorlage. Was ist, wenn ich alle Instanzen dieser Vorlage überschreiben möchte? Dies kann durch Bearbeiten der Vorlage selbst geschehen (Entfernen der Instanzkennung - in diesem Fall tty2):

systemctl edit getty@

Die Umgebung überschreiben

Ein häufiger Anwendungsfall für /etc/defaultDateien ist das Festlegen von Umgebungsvariablen. In der Regel /etc/defaulthandelt es sich um ein Shell-Skript, sodass Sie darin Shell-Sprachkonstrukte verwenden können. Bei systemdist dies jedoch nicht der Fall. Sie können Umgebungsvariablen auf zwei Arten angeben:

Über eine Datei

Angenommen, Sie haben die Umgebungsvariablen in einer Datei festgelegt:

$ cat /path/to/some/file
FOO=bar

Dann können Sie die Außerkraftsetzung hinzufügen:

[Service]
EnvironmentFile=/path/to/some/file

Insbesondere wenn Ihre /etc/default/grubnur Zuweisungen und keine Shell-Syntax enthält, können Sie sie als die verwenden EnvironmentFile.

Über EnvironmentEinträge

Das oben Genannte kann auch mithilfe der folgenden Außerkraftsetzung erreicht werden:

[Service]
Environment=FOO=bar

Dies kann jedoch bei mehreren Variablen, Leerzeichen usw. schwierig werden. Schauen Sie sich eine meiner anderen Antworten an, um ein Beispiel für eine solche Instanz zu erhalten.

Weitere Lektüre

Über diesen Mechanismus ist es sehr einfach, systemdEinheiten zu überschreiben und solche Änderungen rückgängig zu machen (indem einfach die Überschreibungsdatei entfernt wird). Dies sind nicht die einzigen Einstellungen, die geändert werden können.

Die folgenden Links wären nützlich:

muru
quelle
1
Sie müssen die Variable löschen, bevor Sie sie für Dienste festlegen, die nicht vom Typ oneshot sind. Das hat mein Problem gelöst.
Colin
3
@MarkEdington aus der systemd.service(5)Manpage, Abschnitt über ExecStart: "Wenn Type = oneshot ist, muss genau ein Befehl angegeben werden. Wenn Type = oneshot verwendet wird, können null oder mehr Befehle angegeben werden. Befehle können angegeben werden, indem mehrere Befehlszeilen in derselben Zeile angegeben werden Direktive oder alternativ kann diese Direktive mehrmals mit dem gleichen Effekt angegeben werden. Wenn die leere Zeichenfolge dieser Option zugewiesen wird, wird die Liste der zu startenden Befehle zurückgesetzt, vorherige Zuweisungen dieser Option haben keine Wirkung. "
muru
1
@Orient Sie können sudo rmdie Überschreibungsdatei und dann systemctl daemon-reload, oder Sie können systemctl editund ersetzen alles in der Überschreibungsdatei mit Kommentaren. Kommentare in Servicedateien beginnen mit #.
Muru
3
@Orientsystemctl revert foo
Ayell
1
Welche Rangfolge haben die drei Methoden (Datei überschreiben, Umgebungsdatei, Umgebungsvariable)? Dh für eine Variable, die in allen drei definiert ist, welcher Wert wird der effektive sein?
Nikolaos Kakouros