Wie kann ich meinen systemd-Dienst über einen bestimmten Benutzer ausführen und beim Booten starten?

132

Ich habe gerade ein Upgrade von Ubuntu Server 14 auf Version 15 durchgeführt. Ich hatte Probleme, mein Upstart-Skript nach dem Upgrade zum Laufen zu bringen, und habe gelesen, dass systemd der neue Standard ist. Ich bin weit entfernt von einem Linux-Experten, also schont mich bitte :-)

Hier ist, was mein Emporkömmlingsskript vorher war:

description "NZBGet upstart script"

setuid robert
setgid robert

start on runlevel [2345]
stop on runlevel [016]

respawn

expect fork

script
    exec nzbget -D
end script

pre-stop script
    exec nzbget -Q
end script

Basierend auf der Wiki-Seite "Upstart to Systemd" habe ich die dort bereitgestellten Tabellen verwendet, um die Dinge so genau wie möglich in meiner neuen Systemd-Servicedatei abzubilden:

[Unit]
Description=NZBGet Service

[Service]
Type=forking
ExecStart=/usr/local/bin/nzbget -D
ExecStop=/usr/local/bin/nzbget -Q
Restart=on-failure

Diese Datei befindet sich unter /home/robert/.config/systemd/user/nzbget.service. So starten Sie den Dienst manuell:

$ systemctl --user start nzbget

Das funktioniert super. Wenn ich mich jedoch von meiner SSH-Sitzung abmelde, wird der Dienst beendet. Es startet auch nicht beim Booten oder bei der Benutzeranmeldung. Ich möchte, dass es sich genauso verhält wie ein Start-Service: Ich möchte, dass es beim Booten startet, ständig ausgeführt wird und als bestimmter Benutzer.

Was muss ich tun, um diese Konfiguration zu erhalten?

void.pointer
quelle

Antworten:

163

Erstes Problem

Sie können die Anweisungen User=und Group=im [Service]Abschnitt der Unit-Datei angeben .

Zweites Problem

Damit der Dienst beim Booten ausgeführt wird, sollten Sie ihn nicht in Ihrem Home-Ordner ablegen. Legen Sie es stattdessen unter /etc/systemd/system/. Dies ist der Ordner, der vom Systemadministrator (dh von Ihnen) zum Hinzufügen neuer systemweiter Dienste verwendet werden soll.

Andere Ordner umfassen:

  • /usr/lib/systemd/system/ist für Pakete gedacht, die Unit-Dateien installieren möchten, obwohl der Ordner unter Debian und Ubuntu tatsächlich so ist, /lib/systemd/system/weil die verschiedenen Ordner binund libnoch nicht zu einem einheitlichen /usr/Präfix zusammengeführt wurden.
  • /usr/local/systemd/system/ dient zum Installieren von Einheiten durch lokal kompilierte Pakete.

Gerät testen

Sobald sich die Gerätedatei an einem geeigneten Ort befindet, können Sie versuchen, das Gerät sofort zu starten, indem Sie systemctl start <UNIT_FILENAME>wie gewohnt eingeben . Es sollte funktionieren, ohne den vollständigen Pfad des Geräts eingeben zu müssen. Die Erweiterung muss auch nicht angegeben werden, wenn es ist .service.

Gerät aktivieren

Bevor Sie Ihr Gerät aktivieren können, müssen Sie einen [Install]Abschnitt hinzufügen , unter dem Sie die Direktive hinzufügen sollten WantedBy=multi-user.target. Diese Anweisung gibt die Phase des Startvorgangs an, in der der Dienst gestartet werden soll (sofern aktiviert). multi-user.targetist für die meisten Dienste geeignet.

Sobald diese Informationen hinzugefügt wurden, können Sie diese verwenden systemctl enable <UNIT_FILENAME>, um das Gerät zu aktivieren, sodass systemd es ab jetzt automatisch während des Startvorgangs in der angegebenen Phase startet.

Yamaho
quelle
Das hat funktioniert. Ich musste den absoluten Pfad zum Dienstdateinamen im systemctl enableBefehl angeben , dies war mir zunächst nicht klar. Das Aktivieren warnte mich auch vor einem fehlenden [Install]Abschnitt. Ich habe es ignoriert, bin mir aber nicht sicher, ob es die Fähigkeit beeinträchtigen wird, beim Booten zu starten.
void.pointer
2
Die InstallWarnung war eigentlich sehr wichtig. Es startet nicht beim Booten ohne WantedBy=multi-user.targetunter dem [Install]Abschnitt. Nach dem Hinzufügen dieser auf die .serviceDatei, dann können Sie enablees.
void.pointer
4
Ich entschuldige mich dafür, dass ich die Antwort so lange unbeaufsichtigt gelassen habe. Ich habe den Speicherort der Unit-Datei korrigiert und die fehlenden Informationen zu dem [Install]Abschnitt hinzugefügt . Hoffe, es ist jetzt hilfreicher für alle, die danach suchen.
Yamaho
5
Das wird viel einfacher , wenn der Benutzername auf Vorlagen, dh Ihr Dienst mit einem Dateinamen im Format definiert wird [email protected]dann enablemöchte [email protected]die Einstellung wird User=%iden Benutzer bedeutet nicht hartcodiert und können mehr Benutzer die gleiche Definition verwenden. Ein Beispiel.
Walf
1
Fängt es an, wenn ich es drunter lege /etc/systemd/user/?
Khurshid Alam
46

Möglicherweise möchten Sie die "User Lingering" -Funktionalität von systemd nutzen. Es wird über aktiviert loginctl enable-linger USERNAME.

Es wird ein separater Service Manager für den jeweiligen Benutzer beim Booten gestartet, sodass Ihre benutzerdefinierten Einheiten ~/.config/systemd/userbeim Booten und Herunterfahren entsprechend Ihrer Servicekonfiguration abgeholt und verarbeitet werden.

Sie können auch systemctl --userzum Verwalten und Konfigurieren der Dienste verwendet werden, die auf dem Dienstmanager Ihres Benutzers und nicht auf dem des Systems ausgeführt werden.

byteborg
quelle
6
systemctl --userist eine fantastische Entdeckung. Vielen Dank!
Anwar
@byteborg Vielleicht kannst du zu unix.stackexchange.com/questions/409900/… beitragen ? Ich brauche Abhängigkeit von PostgreSQL im Nutzerdienst, aber die Datenbank bleibt der Systemdienst, nicht der Nutzerdienst.
Michał F
1
Gibt es Techniken, die es dem Benutzer ermöglichen, die Protokolle des Dienstes anzuzeigen, sobald die Dienste ausgeführt werden? Ein nicht privilegierter Benutzer könnte nicht nach / var / log / syslog gelangen.
16.
2
Beachten Sie, dass systemctl --userdies für SSH-Sitzungen anscheinend nicht funktioniert.
Mark K Cowan
2
Sollte die akzeptierte Lösung sein
Drew