GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Veranlassen, dass ein Skript ausgeführt wird, nachdem das Netzwerk gestartet wurde?

Ich bin relativ neu in systemd und lerne seine Architektur.

Im Moment versuche ich herauszufinden, wie ich ein benutzerdefiniertes Shell-Skript zum Ausführen bringen kann. Dieses Skript muss nach ausgeführt werden die Netzwerkschicht wurde gestartet.

Ich verwende Arch und verwende sowohl systemd als auch netctl.

Zum Testen habe ich ein einfaches Skript geschrieben, das einfach ip addr list > /tmp/ip.txt ausführt . Ich habe die folgende Dienstdatei für dieses Skript erstellt.

(/etc/systemd/system/test.service)
[Unit]
Description=test service

[Service]
ExecStart=/root/test.script

[Install]
WantedBy=multi-user.target

Ich habe dann das Skript mit aktiviert,

systemctl enable test

Beim Neustart wird das Skript zwar ausgeführt, aber es wird ausgeführt, bevor das Netzwerk gestartet wird. Also die Ausgabe in ip.txt zeigt der primären Schnittstelle keine zugewiesene IPv4-Adresse an. Als ich mich anmelde, ist die IPv4-Adresse tatsächlich zugewiesen und das Netzwerk ist aktiv.

Ich schätze, ich könnte den Punkt ändern, an dem das Skript ausgeführt wird, indem ich mit WantedBy herumspiele Parameter, aber ich bin mir nicht sicher, wie das geht.

Könnte mich jemand in die richtige Richtung weisen?

Akzeptierte Antwort:

Über Systemd-Netzwerkkonfigurationsabhängigkeiten

Es ist sehr einfach, die Einheitenreihenfolge von systemd zu beeinflussen. Andererseits müssen Sie darauf achten, was eine fertige Einheit garantiert.

Konfigurieren Sie Ihren Dienst

Auf aktuellen Systemen
nach network.target bestellen garantiert nur, dass der Netzwerkdienst gestartet wurde, nicht, dass es eine tatsächliche Konfiguration gibt. Sie müssen nach network-online.target bestellen und ziehen Sie es hinein, um das zu erreichen.

[Unit]
Wants=network-online.target
After=network-online.target

Für die Kompatibilität mit älteren Systemen müssen Sie möglicherweise auch nach network.target bestellen.

[Unit]
Wants=network-online.target
After=network.target network-online.target

Das gilt für die Unit-Datei Ihres Dienstes und für systemd.

Implementierung in aktuellen Softwareversionen

Jetzt müssen Sie sicherstellen, dass network-online.target wie erwartet funktioniert (oder dass Sie zumindest network.target verwenden können ).

Die aktuelle Version von NetworkManager bietet den NetworkManager-wait-online.service an die von network-online.target eingezogen wird und damit durch Ihren Dienst. Dieser spezielle Dienst stellt sicher, dass Ihr Dienst wartet, bis alle für den automatischen Start konfigurierten Verbindungen erfolgreich sind, fehlschlagen oder eine Zeitüberschreitung aufweisen.

Die aktuelle Version von systemd-networkd blockiert Ihren Dienst, bis alle Geräte wie gewünscht konfiguriert sind. Es ist insofern einfacher, als es derzeit nur Konfigurationen unterstützt, die zur Bootzeit angewendet werden (genauer gesagt zur Startzeit von `systemd-networkd.service).

Der Vollständigkeit halber die /etc/init.d/network Der Dienst in Fedora, wie er von den aktuellen Versionen von systemd interpretiert wird, blockiert network.target und blockiert somit indirekt network-online.target und Ihren Dienst. Es ist ein Beispiel für eine skriptbasierte Implementierung.

Wenn sich Ihre Implementierung, ob daemon- oder skriptbasiert, wie einer der oben genannten Netzwerkverwaltungsdienste verhält, verzögert sie den Start Ihres Dienstes, bis die Netzwerkkonfiguration entweder erfolgreich abgeschlossen ist, aus gutem Grund fehlgeschlagen ist oder nach einer angemessenen Zeit abgelaufen ist Frame zu vervollständigen.

Verwandte:Nach Dateien suchen, deren Pfadnamen mehrere Wörter ohne bestimmte Reihenfolge zwischen ihnen enthalten?

Sie sollten überprüfen, ob netctl funktioniert auf die gleiche Weise und diese Informationen wären eine wertvolle Ergänzung zu dieser Antwort.

Implementierungen in älteren Softwareversionen

Ich glaube nicht, dass Sie eine ausreichend alte Version von systemd sehen werden, wo dies nicht gut funktionieren würde. Aber Sie können das zumindest network-online.target überprüfen existiert und dass es nach network.target geordnet wird .

Früher NetworkManager nur garantiert, dass mindestens eine Verbindung angelegt wird. Und selbst damit das funktioniert, müssten Sie den NetworkManager-wait-online.service aktivieren ausdrücklich. Dies wurde in Fedora schon lange behoben, wurde aber erst vor kurzem von den Upstreams angewendet.

systemctl enable NetworkManager-wait-online.service

Hinweise zu network.target- und network-online.target-Implementierungen

Sie sollten Ihre Software niemals von NetworkManager.service abhängig machen müssen oder NetworkManager-wait-online.service noch irgendwelche anderen spezifischen Dienstleistungen. Stattdessen sollten sich alle Netzwerkverwaltungsdienste vor network.target einordnen und optional network-online.target .

Ein einfacher skriptbasierter Netzwerkverwaltungsdienst sollte die Netzwerkkonfiguration vor dem Beenden abschließen und sich selbst vor network.target anordnen und damit indirekt vor network-online.target .

[Unit]
Before=network.target

[Service]
Type=oneshot
ExecStart=...
RemainAfterExit=yes

Ein Daemon-basierter Netzwerkverwaltungsdienst sollte sich ebenfalls vor network.target anordnen auch wenn es nicht sehr nützlich ist.

[Unit]
Before=network.target

[Service]
Type=simple
ExecStart=...

Ein Dienst, der darauf wartet, dass der Daemon beendet wird, sollte sich nach dem bestimmten Dienst und vor network-online.target anordnen . Es sollte Requisite verwenden auf dem Daemon-Dienst, sodass dieser sofort fehlschlägt, wenn der entsprechende Netzwerkverwaltungsdienst nicht verwendet wird.

[Unit]
Requisite=...
After=...
Before=network-online.target

[Service]
Type=oneshot
ExecStart=...
RemainAfterExit=yes

Das Paket sollte einen symbolischen Link zum wartenden Dienst in wants installieren Verzeichnis für network-online.target damit es von Diensten angezogen wird, die auf das konfigurierte Netzwerk warten wollen.

ln -s /usr/lib/systemd/system/... /usr/lib/systemd/system/network-online.target.wants/

Zugehörige Dokumentation

  • http://www.freedesktop.org/software/systemd/man/systemd.special.html#network-online.target
  • http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/

Schlussbemerkungen

Ich hoffe, ich habe nicht nur geholfen, Ihre Frage zu dem Zeitpunkt zu beantworten, als Sie sie gestellt haben, sondern auch dazu beigetragen, die Situation in Upstream- und Linux-Distributionen zu verbessern, sodass ich jetzt eine bessere Antwort geben kann, als dies zum Zeitpunkt des Schreibens der ursprünglichen möglich war .


Linux
  1. Linux-Betriebssystemdienst „scsi_reserve“

  2. Ruby-Skript als Dienst

  3. Nach der Installation von Jenkins kann Benutzer Jenkins nicht aufgerufen werden

  4. Führen Sie das Bash-Skript als Daemon aus

  5. Wie führt man ein Bash-Skript aus?

Erste Schritte mit systemctl

So führen Sie Shell-Skript als SystemD-Dienst in Linux aus

Wie führe ich einen Befehl in einem Shell-Skript aus?

Centos 7:Erste Schritte

Führen Sie das Bash-Skript nach der Anmeldung aus

Wie führe ich ein Skript mit systemd kurz vor dem Herunterfahren aus?