systemd - Ich gebe meinem Dienst mehrere Argumente

44

Kann ich meinem systemd-Dienst mehr als ein Argument geben?

Ich möchte ein Programm mit mehreren Argumenten ausführen, über die der Endbenutzer entscheiden muss.

Z.B: ./program arg1 arg2

Um eine App mit einem einzigen Argument zu starten, bräuchte ich so etwas wie systemctl start arg1@program, wo ich in der Service-Definition habe ExecStart = /usr/bin/program ℅i.

Vielen Dank!

peperunas
quelle
1
Klingt nach einer Konfigurationsdatei.
Daniel B
Ich muss es unterwegs ändern. Brauche ich unbedingt eine conf-Datei?
Peperunas
@ peperunas Sie brauchen keine Conf-Datei, siehe meine Antwort, die ohne zusätzliche Dateien
funktioniert

Antworten:

34

Ja, du kannst! Definieren Sie sie irgendwo in einer Datei und fügen Sie sie EnvironmentFileIhrem systemd-Dienst hinzu. Angenommen, der Inhalt von /etc/.progconf lautet:

ARG1=-o
ARG2=--verbose

Und Ihre .service-Datei:

EnvironmentFile=/etc/.progconf
ExecStart = /usr/bin/prog $ARG1 $ARG2

Sie können in diese Datei schreiben, wenn Sie sie unterwegs ändern müssen. Ein Service sollte seine Optionen nicht sehr oft ändern. Vielleicht sollten Sie einen Autostart oder einen Cron in Betracht ziehen, wenn Sie dies benötigen.

Weitere Beispiele finden Sie unter: https://wiki.archlinux.org/index.php/Systemd/Services

platforma
quelle
Heh, ganz praktisch, hat nicht daran gedacht. Ich muss allerdings zustimmen: Service-Parameter ändern sich nicht regelmäßig und auch nicht ihre Konfigurationsdateien.
Daniel B
Wenn die Servicedatei Umgebungsvariablen verwendet, können Sie sagen VAR1=... VAR2=... systemctl start foobar.service, dass die Variablen übergeben werden sollen?
Johannes Schaub - litb
Ja, ich glaube, Sie können
Plattforma
6
@ JohannesSchaub-litb, nein, das kannst du nicht. Es gibt eine PassEnvironmentDirektive, aber sie nimmt Variablen aus dem systemdProzess (normalerweise PID 1) und nicht aus systemctl. Umgebungsvariablen aus dem systemctlProzess werden nicht an den zu startenden Dienst weitergegeben.
cjm
2
Upstart kann jedoch mehrere Instanzen desselben Dienstes mit unterschiedlichen Parametern ausführen. Zum Beispiel ein Mailserver auf eth0 und eine andere Instanz des Mailservers auf eth1, der den Parameter an upstart übergibt und diese als separate Dienste verwaltet. Kann systemd das tun?
LtWorf
15

Ich wollte dasselbe tun, aber ohne eine separate Datei für jede Kombination von Argumenten. Ich fand heraus, dass ich ein langes Argument mit Leerzeichen übergeben und dann die Funktion zur Aufteilung der Umgebungsvariablen von systemd verwenden konnte, um die Argumente zu trennen.

Ich habe einen Dienst mit Dateiname erstellt [email protected]( beachten Sie das abschließende 'at-Zeichen', das erforderlich ist, wenn ein Dienst Argumente akzeptiert ).

[Unit]
Description=Test passing multiple arguments

[Service]
Environment="SCRIPT_ARGS=%I"
ExecStart=/tmp/test.py $SCRIPT_ARGS

Ich betreibe diese mit sudo systemctl start argtest@"arg1 arg2 arg3".serviceund es geht arg1, arg2und arg3als separate Befehlszeilenargumente zu test.py.

nonagon
quelle
"Beachten Sie das nachgestellte kaufmännische Und": Ich finde kein kaufmännisches Und in Ihrer Antwort. Können Sie Ihre Antwort bearbeiten, um diesbezüglich klarer zu sein?
Patrick Mevzek
Ja, tut mir leid!
Nonagon
Ich denke, das @ wird nur benötigt, wenn Sie das% I so verwenden, wie Sie es tun. Es ist eine Instanz des Dienstes.
Toby
Einverstanden bin ich nur auf ein paar Blogposts gestoßen, die es weggelassen haben. Ich werde in meiner Antwort klären.
Nonagon
Dies scheint nicht innerhalb eines anderen Dienstes zu funktionieren. Ich habe es versucht Wants=argtest@"arg1 arg2".serviceund nur das erste Argument wurde übergeben.
Roger Dueck
1

Am einfachsten habe ich gefunden:

ExecStart=/bin/bash -c "\"/path/with spaces/to/app\" arg1 arg2 arg3 \"arg with space\""

Hält alles in sich geschlossen.

Allerdings habe ich festgestellt, dass ich das zumindest auf Ubuntu 18.04 LTS nicht einmal tun muss. Ich kann das und es funktioniert einwandfrei:

ExecStart="/path/with spaces/to/app" arg1 arg2 arg3 "arg with space"

$vars Arbeite auch mit diesem Muster als Argument.

jjxtra
quelle