Das systemd-notify
Tool ist speziell für eine Shell gedacht, die als systemd-Dienst ausgeführt wird Type=notify
.
Wenn Sie einen Dienst mit Type=notify
einrichten, richtet systemd automatisch einen Kommunikationssocket wieder auf systemd ein und exportiert seinen Pfad zum Dienst unter $NOTIFY_SOCKET
.
Es wartet auch auf spezielle Nachrichten in diesem Socket, z. B. ob der Dienst bereit ist (in diesem Fall wechselt das Systemd nach Abschluss der started
Initialisierung in den Status ), und es wird auch der selbst gemeldete Status des Dienstes gemeldet in der Ausgabe von systemctl status mytest.service
(vorausgesetzt, ein Dienst wird aufgerufen mytest
.)
Sie können die Manpage vonsystemd-notify
für alle Details lesen , obwohl es dort viel Komplexität gibt ... Vielleicht ist das Beispiel am Ende nützlich, um zu veranschaulichen, wie es funktioniert.
Lassen Sie uns dieses Beispiel für ein praktisches Experiment verwenden!
Erstellen Sie ein Skript wie das folgende irgendwo in Ihrem System, wie zum Beispiel /usr/local/bin/mytest.sh
:
#!/bin/bash
mkfifo /tmp/waldo
sleep 10
systemd-notify --ready --status="Waiting for data…"
while : ; do
read a < /tmp/waldo
systemd-notify --status="Processing $a"
# Do something with $a …
sleep 10
systemd-notify --status="Waiting for data…"
done
Ich habe ein paar sleep 10
s hinzugefügt, damit Sie sehen können, was passiert, wenn Sie sich die systemctl status mytest.service
Ausgabe ansehen .
Machen Sie das Skript ausführbar:
$ sudo chmod +x /usr/local/bin/mytest.sh
Dann erstelle /etc/systemd/system/mytest.service
mit Inhalten:
[Unit]
Description=My Test
[Service]
Type=notify
ExecStart=/usr/local/bin/mytest.sh
[Install]
WantedBy=multi-user.target
Laden Sie dann systemd neu (damit es etwas über das Gerät erfährt) und starten Sie es:
$ sudo systemctl daemon-reload
$ sudo systemctl start mytest.service
Dann schauen Sie sich immer wieder die Statusausgabe an:
$ systemctl status mytest.service
Sie werden sehen, dass es starting
für die ersten 10 Sekunden ist, danach wird es sein started
und sein Status wird "Warten auf Daten ..." sein.
Schreiben Sie nun einige Daten in das FIFO (Sie müssen tee
sie als root ausführen):
$ echo somedata | sudo tee /tmp/waldo
Und beobachten Sie den Status:
$ systemctl status mytest.service
Der Status des Dienstes wird 10 Sekunden lang als "Daten werden verarbeitet" und dann wieder als "Warten auf Daten ..." angezeigt.
Wenn Sie diesen Code in C oder einer anderen Sprache schreiben würden, die systemd-Bindungen unterstützt, würden Sie die sd_notify()
Funktion für diesen Zweck verwenden. Wenn Sie mit C vertraut sind, sollten Sie einen Blick auf die Manpage sd_notify (3) werfen .
systemd-notify
muss mitfifo
Datei arbeiten? Ich meine, wir, die Benutzer, müssen einen Kommunikationsweg anbieten, dersystemd-notify
funktionieren kann. Ich dachte,systemd-notify
ich hätte eine Methode, um eine eigene Art der Kommunikation aufzubauen ...fifo
hat nichts damit zu tunsystemd-notify
. Filbranden hat es hier nur für das Beispielskript verwendet, um das Skript aus einem anderen Fenster heraus zu kitzeln ./tmp/waldo
Fifo ist nur ein sehr sehr einfacher Server, um ein Beispiel zu veranschaulichen. Meine ursprüngliche Idee für ein Beispiel war ein Zählerskript (setze den Status auf$i
, inkrementierei
, schlafe eine Sekunde, Schleife.) Das kannst du auch versuchen.systemd-notify
möchte den Socket zurück zu systemd finden und das ist es, was (von systemd) exportiert wird$NOTIFY_SOCKET
, aber das ist hauptsächlich ein Implementierungsdetail zwischen zwei Teilen von systemd selbst ... Ich hoffe, das macht SinnType=notify
und seine Verwendung, das ist es, was dies ist alles über.Keine vollständige Antwort, aber ich bin so weit gekommen
netcat
:export NOTIFY_SOCKET=/tmp/test.sock
nc -l -U -u /tmp/test/sock
export NOTIFY_SOCKET=/tmp/test.sock
systemd-notify --read --status="hello"
Das funktioniert, aber auf der
netcat
Seite wirst du bekommennc: connect: Invalid argument
. Ich weiß nicht, wie ich das umgehen soll.quelle
/tmp/test.sock
?