Ich habe einen systemd
Dienst, der unter einem bestimmten Benutzer ausgeführt wird.
Ich bin fälschlicherweise davon ausgegangen, dass der Dienst Zugriff auf die Umgebungsvariablen hat, die alle Benutzer von Skripten/Exporten erben unter/etc/profile.d
Gibt es eine Möglichkeit, dies zu erreichen, ohne die Variablen in systemd
der Unit-Dateidefinition manuell kopieren zu müssen?
Ich habe zum Beispiel folgendes
$ cat /etc/profile.d/somexports
export VAR1=VALUE1
export VAR2=VALUE2
systemd
Kann dies an einen Dienst weitergegeben/exportiert werden ?
Antwort1
Es gibt einige mögliche Umgebungsquellen:
- Mit
Environment=
which können Sie Variablen festlegen - Mit
EnvironmentFile=
which können Sie Werte aus einer Datei laden - Damit
PassEnvironment=
können Sie Variablen definieren, die von PID1 übergeben werden sollen. - Statische Konfiguration (zB
$USER
)
Es klingt vielleicht so, als EnvironmentFile=/etc/profile.d/someexports
ob es das ist, was Sie wollen, aber das ist nicht der Fall. /etc/profile.d/*
wird oft von Ihrer Shell bezogen und kann von Ihrer Shell analysiert werden. systemd
ist Shell-agnostisch und verlässt sich daher nicht auf die Bash-Syntax. Es EnvironmentFile
sollte durch Zeilenumbrüche getrennte Variablenzuweisungen enthalten, was viel strenger ist.
systemd
Das Design von verhindert, dass sich Einheiten oder ihre Umgebungen dynamisch ändern. Sogar die EnvironmentFile=
Option wurde nur aufgrund von Druck hinzugefügt und später von systemd
den Entwicklern als Fehler angesehen. Ein Beispiel für dieses Design ist, dass $PATH
es keinen Einfluss darauf hat, welche Binärdateien verwendet werden. Dadurch bleiben die Dinge deterministischer, da Sie beim Definieren einer Einheit alles darüber definieren, wie diese Einheit ausgeführt werden soll, ohne sich um externe Einflüsse zu kümmern.
Die kurze Antwort lautet also: Nein, Sie können es nicht laden /etc/profile.d/*
und systemd
das ist Absicht.
Aber die Antwort, die Sie wahrscheinlich wollen, ist: Ja, Sie können es laden. Sie müssen Ihre Anwendung nur über eine Shell ausführen.
Sie können dies tun, indem Sie Folgendes ändern:
ExecStart=/usr/bin/myservice
Zu
ExecStart=/usr/bin/bash -lc myservice
Dies führt dazu, bash
dass der übergeordnete Prozess ist, der /etc/profile.d/
diese Umgebung lädt und an sein untergeordnetes Element weiterleitet. Beachten Sie auch, dass ich keinen vollständigen absoluten Pfad zu angegeben habe myservice
. In diesem Fall myservice
basiert auf $PATH
und das kann sein oder auch nicht /usr/bin/myservice
. Sie können sehen, wie dies die Fehlerbehebung erschweren kann, und das ist der Nachteil dieses Weges.
Antwort2
Ich denke, dies wird wie folgt angesprochen
ExecStart=/bin/sh -lc /path/to/binary
Das -l
Flag macht den Shell-Aufruf zu einer Login-Shell. Wir brauchen das, weil nur Login-Shells Profilskripte als Quelle verwenden.
$ bash --help | grep -- -l
GNU bash, version 4.4.12(1)-release-(x86_64-pc-linux-gnu)
--login