Script will nicht, wie ich

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
nephilim
Beiträge: 39
Registriert: 06.03.2017 18:11:50

Re: Script will nicht, wie ich

Beitrag von nephilim » 09.03.2017 06:24:20

Danke Thomas, das verstehe ich.

OK, hier ist, was ich getan habe, um das Vorgeschlagene zu testen.

Ein ganz frisches Debian 8 auf die Karte gezogen, den RPi3 bestückt und update & upgrade gemacht. Dann habe ich die Datei /usr/local/bin/pcf/collect.sh erstellt, mit folgendem Inhalt gefüllt und für ugo ausführbar gemacht:

Code: Alles auswählen

#!/bin/sh
# This script collects basic data and writes them to /etc/pcf/parameter.txt

router=$(netstat -r -n | awk '/UG/ {print $2}')

echo "# This file will be created while startup procedure\n" > /etc/pcf/parameter.txt

echo "IP_EXT=$(curl http://my.ip.fi)" >> /etc/pcf/parameter.txt
echo "IP_INT=$(ifconfig | grep "inet " | grep -v "127*" | sed 's/^[ \t]*//' | cut -d ":" -f2 | cut -d " " -f1)" >> /etc/pcf/parameter.txt
echo "DNS=$router" >> /etc/pcf/parameter.txt
echo "export {IP_EXT} {IP_INT} {DNS}" >> /etc/pcf/parameter.txt

exit 0
Nun habe ich meine Service-Unit erstellt und aktiviert:

Code: Alles auswählen

pi@raspberrypi:~ $ sudo nano /etc/systemd/system/collect.service
pi@raspberrypi:~ $ sudo systemctl enable /etc/systemd/system/collect.service
Created symlink from /etc/systemd/system/multi-user.target.wants/collect.service to /etc/systemd/system/collect.service.
pi@raspberrypi:~ $ sudo systemctl is-enabled collect.service
enabled
pi@raspberrypi:~ $
Und das ist der Inhalt von collect.service:

Code: Alles auswählen

[Unit]
Description=neph:collect.service:   Collects data once the network is up and running
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
TimeoutStartSec=95
ExecStart=/usr/local/bin/pcf/collect.sh

[Install]
WantedBy=multi-user.target
Ich verwende After=network-online.target & Wants=network-online.target weil ich das hier gelesen habe:
Alternatively, you can change your service that needs the network to be up, to include After=network-online.target and Wants=network-online.target.
Hier mein Ergebnis in /etc/pcf/parameter.txt:

Code: Alles auswählen

# This file will be created while startup procedure

IP_EXT=
IP_INT=
DNS=
export {IP_EXT} {IP_INT} {DNS}
Die Werte fehlen immer noch. Woran kann das liegen? Habe ich was wesentliches vergessen?

LG // neph

TomL

Re: Script will nicht, wie ich

Beitrag von TomL » 09.03.2017 10:27:53

nephilim hat geschrieben:Ich verwende After=network-online.target & Wants=network-online.target weil ich das hier gelesen habe:
:D Das finde ich ja mal richtig klasse. Jemand, der eine vorherige Antwort dergestalt weiterverwendet, um sich darüber weitergehend zu informieren, sich eigene Gedanken macht, selber aufgrund von Anregungen recheriert und versucht auf Verstehen basierend konstruktiv zu eigenen Lösungen zu kommen :THX:

Aber leider gerätst Du hier in eine Falle, die Du als Newbie unmöglich selber erkennen kannst. Zunächst mal liegt hier eine Verwechselung vor. Dein Link beschreibt die besondere Service-Unit 'systemd-networkd-wait-online.service'. Diese Unit funktioniert nach meinem Kenntnisstand aber nur, wenn Du das Netzwerk über 'systemd-networkd & systemd-resolved' startest und handhabst. Das ist aber bei einer frischen Debian-Installation so nicht gegeben. Stattdessen wird das Netzwerk traditionell über '/etc/init.d/networking' & '/etc/network/interfaces' & diverse runlevel-Links gestartet. Faktisch bedeutet das, dass diese Units vor diesem Hintergrund eben nicht funktionieren.

Der zweite Irrtum bezieht sich auf das, was Du tatsächlich in die Unit eingetragen hast, und zwar "After=network-online.target & Wants=network-online.target". Diese Einträge funktionieren zwar auch in dem traditionellen sysvinit-Modus, aber sie tun nicht das, was sie vom Namen vorgeben zu tun und auch nicht das, was Du erwartest.
Die Unit 'network-online.target' ist eine aktive Unit, die weitere Service-Starts verzögert, bis das Netzwerk ausreichend etabliert ist. Die Besonderheit liegt hier beim Begriff "ausreichend".... was bedeutet das? Nun, ganz einfach, es bedeutet keine abschließend gültige Zustandsdefinition, sondern nur das, was für bestimmte Aufgaben als ausreichend definiert wird. Es gibt also verschiedene Zustände von "ausreichend", je nach point of view.
Ausreichend für
- die Treiber ist, wenn der Kernel die Hardware erkannt hat
- die Netzwerkprotokolle ist, wenn der Treiber funktionsfähig ist und ein Networkmanager gestartet werden könnte
- den Networkmanager ist, wenn die NICs geöffnet werden können
- den DHCP-Client ist, wenn der Network-Manager die NICs geöffnet hat und nun eine IP bezogen werden kann
- für den User ist, wenn das Netz (Gateway ->Server und Internet) erreichbar ist

Also, die Aussagekraft von "network-online.target" ist abhängig von dem, der dieses Target anzieht.... und das entscheidet der selber. Das könnte also bedeuten:
- Der Start Networkmanager ist veranlasst (Service-Manager)
- Der Start Networkmanager war erfolgreich (Fork exited = 0) (Service-Manager)
- Der Networkmanager wurde erfolgreich gestartet und ist bereit (NWM)
- Das Netzwerk-Interface wurde erfogreich geöffnet (NWM)
- eine DHCP-Adresse wurde angefordert (DHCP)
- eine IP-Adresse ist vergeben (DHCP)
- eine IP-Adresse ist vergeben (NWM)

Darüber hinaus
- beliebige eigene Services können dieses Target nach eigenem Ermessen zu jeder Zeit anziehen

Insofern ist das für Deine Zwecke unbrauchbar. So, und an der Stelle kann man nur hoffen, dass jemand eingreift, wenn ich hier falsches oder unvollständiges erzählt habe. :roll: Wenn Du das genauer wissen möchtest, such einfach mal nach "tcp/ip-referenzmodell". Da siehst Du die Ebenen, die ggf. als "ausreichend" jeweils für den Nachfolger denkbar wären. Wobei das natürlich für unsere Probleme jetzt so auch nicht ganz der Wahrheit entspricht, für uns greifen eher die "späteren" Ebenen, aber egal... was bleibt ist, der Zustand dieses Targets ist nicht vernünftig verwertbar. Und noch weniger auf einem PI, weil es gerade mit dem PI3 auch die Möglichkeit eines eher sehr langsamen Verbindungsaufbaus via internem WLAN-NIC gibt.

PS
Ich denke, diese Antwort macht deutlich, warum man Frage & Antwort nicht per PN abhandeln sollte.
Zuletzt geändert von TomL am 09.03.2017 14:20:15, insgesamt 3-mal geändert.

nephilim
Beiträge: 39
Registriert: 06.03.2017 18:11:50

Re: Script will nicht, wie ich

Beitrag von nephilim » 09.03.2017 10:59:26

Wow, dass nenne ich umfassend. Danke dafür. :)

Ich bin jetzt unsicher. Bedeutet das, ich kann das, was ich vorhabe vergessen, weil nicht realisierbar? Ich weiß das gerade nicht einzuschätzen.

WLAN kann ich vernachlässigen. Der Einsatz später ist nur per LAN definiert. Ich brauche nur eth0.

Wie kann ich denn trotz der Umstände realisieren, was ich da brauche?

LG // neph

TomL

Re: Script will nicht, wie ich

Beitrag von TomL » 09.03.2017 11:04:32

nephilim hat geschrieben:Ich bin jetzt unsicher. Bedeutet das, ich kann das, was ich vorhabe vergessen, weil nicht realisierbar? Ich weiß das gerade nicht einzuschätzen.
Doch, das ist natürlich realisierbar. Die Lösung hatte ich ja schon weiter oben skizziert.... ein explizites Delay, welches auf die definitive Erreichbarkeit einer bestimmten Netzwerkressource wartet, ohne den Boot oder das System oder den Start anderer Services an sich zu blockieren.

Und dann in die Unit collect.service statt after&wants die Einträge übernehmen, wie ich sie oben vorgeschlagen habe, und zwar Warten auf die zweite Unit fürs "Warten aufs Netzwerk". Das wird auf Anhieb funktionieren. Ich würde das auch getrennt/nacheinander umsetzen, insbesondere dabei auch die Log-Einträge durchführen, damit du das jeweils auf Erfolg kontrollieren kannst. Es bringt nix, Dein Scrip zu starten, solange nicht im Log durch diese Wait-Unit drinsteht, dass sie erfolgreich auf das Netzwerk gewartet hat. Und wenn Dein Script danach gestartet wird, muss es erfolgreich sein - sofern keine Fehler drin sind.

nephilim
Beiträge: 39
Registriert: 06.03.2017 18:11:50

Re: Script will nicht, wie ich

Beitrag von nephilim » 09.03.2017 19:52:51

Hoho, ich war so blöd. Ich habe allen Ernstes Deinen Vorschlag oben nicht als funktionierende Lösung wahrgenommen. Hat bissl gedauert, bis es klick gemacht hat.

Dank Deiner Hilfe Thomas, funktioniert es jetzt. :D

Vielen herzlichen Dank für eine richtig angenehme Forum-Erfahrung. Ich habe viel dazugelernt.

LG // neph

nephilim
Beiträge: 39
Registriert: 06.03.2017 18:11:50

Re: Script will nicht, wie ich

Beitrag von nephilim » 11.03.2017 11:57:45

Dieser Eintrag ist optional, aber die Lösung, für die ich mich jetzt entschieden habe. Daher möchte ich sie nachreichen.

Ich habe die Netzwerkverwaltung auf systemd-networkd umgestellt.

Dann habe ich die folgende Service-Unit erstellt. Sie sorgt dafür, dass gewartet wird, bis alle das Netzwerk etabliert wurde und startet dann mein Script; in diesem Beispiel collect.sh.

Service-Unit /etc/systemd/system/<name_deiner_wahl>.service (bei mir: collect.service):

Code: Alles auswählen

[Unit]
Description=neph:collect.service:   Collects data once the network is up and running
After=network.target

[Service]
RemainAfterExit=yes
Type=idle
ExecStart=/usr/local/bin/pcf/collect.sh

[Install]
WantedBy=multi-user.target
Damit After=network.target bei mir funktioniert, musste in meinem Setup noch der folgende "Verzögerungs"-Service aktiviert werden:

Code: Alles auswählen

systemctl enable systemd-networkd-wait-online.service
Hier geht es zur Quelle zum Nachlesen.

Nochmal danke an alle Mitwirkenden..

LG // neph

TomL

Re: Script will nicht, wie ich

Beitrag von TomL » 11.03.2017 14:20:27

nephilim hat geschrieben:Damit After=network.target bei mir funktioniert, musste in meinem Setup noch der folgende "Verzögerungs"-Service aktiviert werden:

Code: Alles auswählen

systemctl enable systemd-networkd-wait-online.service
Hier geht es zur Quelle zum Nachlesen.
Das funktioniert mit Einschränkungen richtig prima. Ich habe das früher auch verwendet. Allerdings zeigt es Dir nur an, dass das Netzwerk verbunden ist und Du eine gültige IP in diesem Netzwerk hast. Leider ist aber keine Information darüber enthalten, ob beispielsweise eine bestimmte Ressource in diesem Netzwerk erreichbar ist oder ob z.B. das Internet erreichbar ist.

Eine bestimmte Ressource könnte ein Fileserver im LAN sein, der sich vielleicht verabschiedet hat. Wenn auf dem Client jedoch bestimmte Jobs genau diesen Fileserver brauchen, für simple Remote-Mounts zu Samba- oder NFS-Shares, für Backups, Homedirs, egal was, reicht leider systemd-networkd-wait-online.service nicht, um die Verfügbarkeit dieses Servers zu gewährlisten. Ebenso kann zwar das LAN laufen, aber der Zugriff aufs WAN ist weg, weil der ISP gerade Schluckauf hat oder ein Bagger die Leitung gekappt hat. Auch das handhabt der Service nicht. Das bedeutet, man muss für bestimmte Jobs zusätzlich ein Fallback-Szenario entwerfen, weil sie ja trotzdem gestartet werden. Deswegen habe ich das wieder ausgeplant und starte bestimmte Jobs nur, wenn auch die gewünschte Ressource verfügbar ist. Genau diese Schwäche sollte meine network_wait_online.service-Alternative beheben. Und ich wollte natürlich keine 2 Delays, das ist natürlich auch Quatsch.

Man muss einfach abwägen, ob es für die eigenen Aufgaben reicht oder nicht oder welche Version für die eigenen Vorhaben besser geeignet ist.

breakthewall
Beiträge: 507
Registriert: 30.12.2016 23:48:51

Re: Script will nicht, wie ich

Beitrag von breakthewall » 13.03.2017 00:54:32

nephilim hat geschrieben:

Code: Alles auswählen

#! /bin/sh
# This script collects basic data and writes them to /etc/pcf/parameter.txt

LOG="/etc/pcf/parameter.txt"

COLLECT() {
echo "IP_EXT=$(ip route | awk '/src / {print $9}')"
echo "IP_INT=$(ip route | tail -1 | awk '{print $1}')"
echo "DNS=$(awk '{print $2}' /etc/resolv.conf | sed '2q;d')"
echo "GATEWAY=$(ip route | awk '/default/ {print $3}')"
export DNS IP_EXT IP_INT GATEWAY
}

COLLECT > "$LOG"

exit 0
Ich habe dein Shellscript mal etwas effizienter gestaltet und fehlerbereinigt. Zum einen hast recht umständliche Wege genutzt um jene Datensätze zu sammeln. Zum anderen ist es unvorteilhaft vielfache Umleitungen auf eine Datei laufen zu lassen, wenn man das wie hier als Funktion, oder via Kommandogruppierung { command; command; } > File, auf einmal zusammenfassen kann. Deine export Zeile im Shellscript war auch nicht korrekt und gewissermaßen wirkungslos, sodass hier ausschließlich echo nur die Variablennamen samt Curly-Brackets ausgegeben hat, ohne das überhaupt irgendetwas exportiert wurde. Wenn man etwas exportiert, dann will man ja letztlich Daten weiterverarbeiten, und wenn offenbar nicht auffällt, dass das gar nicht funktioniert, dann wirkt der Export an sich wieder überflüssig.

nephilim
Beiträge: 39
Registriert: 06.03.2017 18:11:50

Re: Script will nicht, wie ich

Beitrag von nephilim » 13.03.2017 10:55:23

Jetzt bin ich total durcheinander. Vorgestern habe ich ja noch hier die Option beschrieben, für die ich mich entschieden hatte.

Heute funktioniert die nicht mehr. Wie kann denn sowas sein? Und vor allem, wie komme ich dahinter, was da schiefläuft?

Hier die ServiceUnit:

Code: Alles auswählen

[Unit]
Description=neph:collect.service:   Collects data once the network is up and running
After=network.target

[Service]
RemainAfterExit=yes
Type=idle
ExecStart=/usr/local/bin/pcf/collect.sh

[Install]
WantedBy=multi-user.target
LG // ein verwunderter neph

TomL

Re: Script will nicht, wie ich

Beitrag von TomL » 13.03.2017 11:52:18

nephilim hat geschrieben:Jetzt bin ich total durcheinander. Vorgestern habe ich ja noch hier die Option beschrieben, für die ich mich entschieden hatte.
Wie ich im Vorposting schon sagte... das funktioniert mit Einschränkungen richtig prima. Wegen der Einschränkungen habe ich diese Lösung allerdings dort wieder verworfen, wo konkrete Abhängigkeiten bestehen und nutze stattdessen meine Unit plus Script.

Schau Dir Status und die Log-Einträge an, ob Du was findest:

Code: Alles auswählen

systemctl status systemd-networkd systemd-networkd-wait-online.service

journalctl -b -u systemd-networkd-wait-online.service
journalctl -b -u systemd-networkd 
journalctl -p err
journalctl -p warning
Schau Dir die Ausgabe mit einem Picture-Viewer an.... Startzeit und Dauer und Reihenfolge ist dabei interessant

Code: Alles auswählen

systemd-analyze plot >~/bootplot.svg

nephilim
Beiträge: 39
Registriert: 06.03.2017 18:11:50

Re: Script will nicht, wie ich

Beitrag von nephilim » 13.03.2017 12:12:32

Danke Thomas,

begebe mich damit auf die Suche. Haber aber jetzt Deine Lösung implementiert. Mir scheint, damit bin ich "freier".

Nochmals vielen Dank.

LG // neph

Antworten