Raspberry Pi Neustart

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
PaulanerSpezie
User
Beiträge: 6
Registriert: Donnerstag 13. Oktober 2022, 10:01

Hallo zusammen,
Wo kann ich einstellen, dass der Raspberry Pi nach jeden Neustart eine gewisse Python-Datei ausführt?
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Indem du eine systemd Unit dafür schreibst.
PaulanerSpezie
User
Beiträge: 6
Registriert: Donnerstag 13. Oktober 2022, 10:01

__deets__ hat geschrieben: Montag 21. November 2022, 11:46 Indem du eine systemd Unit dafür schreibst.

Und die finde ich wo?

bzw. was sind die allgemeinen Schritte?
Benutzeravatar
Dennis89
User
Beiträge: 1155
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

https://wiki.ubuntuusers.de/systemd/Units/

Anleitungen dazu gibt es viele im Netz.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Johnes
User
Beiträge: 7
Registriert: Mittwoch 23. November 2022, 19:58

In den meisten Anwendungsfällen reicht doch ein Cron-Aufruf dafür aus.

Auf dem Terminal "crontab -e" eingeben und dann eine weitere Zeile einfügen

Code: Alles auswählen

@reboot   python /Pfad/zum/Python/script.py > /dev/null 2>&1
Wenn man "nano" als Editor nutzt, dann mit Strg+O speichern und mit Strg+X den Editor verlassen.

Zumindest starte ich die meisten meiner Pi's so, wenn sie etwas nach dem Reboot ausführen sollen.

MfG
Johnes
nezzcarth
User
Beiträge: 1634
Registriert: Samstag 16. April 2011, 12:47

Johnes hat geschrieben: Mittwoch 23. November 2022, 20:07 Zumindest starte ich die meisten meiner Pi's so, wenn sie etwas nach dem Reboot ausführen sollen.
Das gehört leider zu den Dingen, die sich aus irgendeinem Grund hartnäckig im Raspberry Pi Bereichen halten, obwohl sie eigentlich nicht unbedingt Stand der Technik sind. Fast alle modernen Linux-Distributionen setzen Systemd ein. Mit der Cron-Methode arbeitet man im Prinzip drum herum, benutzt die Vorteile nicht und führt einen Parallelmechanismus ein. Crond selbst wird auch über Systemd gestartet.
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Insbesondere nimmt man sich so die ganzen Vorteile eines Services. Wie zum Beispiel den Neustart bei einem unerwarteten Endes, etc
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Und die Ausgaben in einer Protokolldatei statt das die in /dev/null verschwinden.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Johnes
User
Beiträge: 7
Registriert: Mittwoch 23. November 2022, 19:58

Ich hab jetzt nicht gelesen, er benötigt das Script immer im Hintergrund. Soll nur beim Start ausgeführt werden. Und, wie er die Aisgabe umleitet, ist ja ihm überlassen. Ich benötige i.d.R. die Ausgabe oder den Traceback nicht, wenn ich ein fertiges Script starten lasse. Nen "Dienst" im Hintergrund sollte man natürlich anders starten. Aber zeitgesteuerte Ausführung bzw. einmaliger Start an Punkt X funktioniert mit Cron eigentlich ziemlich gut. Da wäre anderes eben Kanone/Spatz...

MfG
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Und, wie er die Aisgabe umleitet, ist ja ihm überlassen.
Ja - aber das gute ist, dass systemd sich automatisch darum kümmert.

Plus beim Start über crontab hast du keine Kontrolle, wenn zum Zeitpunkt des Neustarts von systemd "on the fly" in eine Unit Service umgewandelt wird.

Plus wir wissen nicht, was das Skript macht ob es z.B. eine Netzwerkverbindung braucht. Da fährt man mit der Flexibilität von systemd deutlich besser.
Aber zeitgesteuerte Ausführung bzw. einmaliger Start an Punkt X funktioniert mit Cron eigentlich ziemlich gut.
Ist aber nun mal semi-veraltet. systemd Units, Service und / oder Timer Units, sind nun mal Stand der Dinge.
Aber in Linux-Universum hat es ja nun mal leider auch eine lange Tradition, an alten Techniken festzuhalten und diese trotz besserer Alternativen zu Propagieren.

Gruß, noisefloor
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Johnes: Wie kann man Ausgabe oder Tracebacks *nicht* benötigen? Ist ja nicht so als wenn niemals etwas nicht funktionieren würde, und man herausfinden möchte *was* schief gelaufen ist. Den Rückgabecode verrät einem systemd in dem Fall auch. Und systemd schaut auch, das nicht unendlich viel protokolliert wird, das heisst man muss sich auch keine Sorgen machen, dass der Hintergrundspeicher voll läuft, wie bei einer einfachen Umleitung per > oder >> in eine Datei.

Neustart bei unerwartetem Ende betrifft nicht nur Programme die immer im Hintergrund laufen. Auch bei einmaligen Sachen beim Systemstart, kann es Sinn machen die ein paar mal zu probieren, falls sie abbrechen, bevor man endgültig aufgibt — oder es eben doch noch klappt.

Ich sehe da auch die Kanone nicht wirklich. Das ist ja letztlich statt einem Eintrag in der crontab, bloss eine kleine Ini-Datei mit zwei/drei Abschnitten die jeweils so 4-5 Zeilen enthalten. Und man muss die auch nicht komplett selber schreiben, sondern kann einen vorhandenen, ähnlichen Dienst als Vorlage verwenden und muss da nur sehr wenig ändern.

Und man kann auch Abhängigkeiten angeben, zum Beispiel, dass man Netzwerk braucht, oder ein bestimmter Server schon vorher gestartet sein muss, was in crontab & Co oft mit so hässlichen Hacks wie ``sleep`` versucht wird ”sicherzustellen”.

@noisefloor: Das ist nicht nur im Linux-Universum so. Dieses „never change a running system“ als Ausrede Code über laaaange Zeiträume nicht anzufassen, auch wenn es mittlerweile bessere APIs gibt, und bei den ursprünglich verwendeten APIs das Wort „deprecated“ ein hohe Frequenz in der Dokumentation hat, findet man auch bei Windows. Keine Ahnung wie es im Mac-Universum aussieht.

Wer so drauf ist, dem kann ich aus Erfahrung 8-Bit-Rechner oder DOS empfehlen. Es ist nicht so, dass sich da gar nichts mehr ändert, aber die Geschwindigkeit der Änderungen ist überschaubar. 🤓
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Apple deprecated wirklich. Und schnell. Das hat seine eigenen Probleme, aber alte Zöpfe mal wirklich zu kappen sorgt für bessere Software, die APIs entwickeln sich ja.
Johnes
User
Beiträge: 7
Registriert: Mittwoch 23. November 2022, 19:58

__blackjack__ hat geschrieben: Donnerstag 24. November 2022, 09:45 @Johnes: Wie kann man Ausgabe oder Tracebacks *nicht* benötigen?
Indem man es einfach nicht benötigt! Ich habe einen etwas zickigen Wechselrichter. Dieser antwortet gerne mal mit einem fehlerhaften unvollständigen Frame (Bitfehler) oder gar nicht. Teilweise crasht im WR der Schnittstellenbaustein und setzt die Verbindung zurück. Wenn ich den WR abfrage und der mal wieder nur Schrott rüber sendet, welches noch nicht berücksichtigt wurde, crasht das Programm. Bei der nächsten Abfrage einige Minuten später, ist alles wieder okay. Ich brauche das Traceback in dem Fall nicht. Warum auch! Der Fehler ist nicht behebbar. Ist ein bekanntes Problem und der Hersteller will kein Firmware-Update bringen. Da die Schnittstelle offiziell nicht für den Endkunden ist, hab ich da auch schlechte Karten. Ich hab es soweit am laufen, das ich die Daten loggen kann. Also "HuKaries"!

Gleiches, wenn ich beim Reboot nur ein "Hier bin ich wieder!" per UDP an meine Gebäudesteuerung sende. Programm läuft, wird quittiert und beendet. Wenn es nicht klappt, ist es auch nicht schlimm. Mülle mir aber auch nicht die SD-Karten mit Logs voll und schmeiße die nach 1-2 Jahren in den Müll. Ständig diese zu beschreiben ist auch nicht gut. Ein Pi1-512 läuft bei mir seit kurz nach dem er auf dem Markt ist quasi durch. Uptime >3kdays mit der ersten SD-Karte. (Und einer der ersten Rasbians! :o )
Und man kann auch Abhängigkeiten angeben, zum Beispiel, dass man Netzwerk braucht, oder ein bestimmter Server schon vorher gestartet sein muss, was in crontab & Co oft mit so hässlichen Hacks wie ``sleep`` versucht wird ”sicherzustellen”.
Schon mal versucht den Netzwerk-Status zu testen, bevor einfach mal nen langes Nickerchen in den Code implementiert wird?
Wer so drauf ist, dem kann ich aus Erfahrung 8-Bit-Rechner oder DOS empfehlen. Es ist nicht so, dass sich da gar nichts mehr ändert, aber die Geschwindigkeit der Änderungen ist überschaubar. 🤓
Ich weiß nicht, warum du jetzt auf meinem Osborne Z80 rumhacken willst. Der hat dir nichts getan! Und DOS funktioniert da drauf nicht so gut. Quasi gar nicht.

Fazit:
Es gibt mehrere Methoden um ein Script beim Reboot zu starten. Ich werde es so machen, wie ich es will. Es taucht ja keine "deprecated-Polizei" an meiner Haustür auf. Der TE kann es auf verschiedene beschriebene Arten machen, wie er es will.
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Klar kann man das machen, wie man will. Wenn man sich allerdings wertend ueber die Herangenhensweise anderer auessert - "Kanone/Spatz" zb - dann wird man sich auch damit abfinden muessen, dass der eigene Ansatz mal genauer betrachtet wird. Und schoen, dass *du* Fehler selbst beurteilen kannst. Der 08/15 user, der schon damit ueberfordert ist, Berechtigungen und relative Pfade zu jonglieren, kann das eher nicht. Klar muss man dann "nur" die Dateiumleitung aendern. Muss man aber auch wissen, wie. Stattdessen ein simples Kommando, das diese Fehlermeldung fuer die Leute hier oder wo auch immer reproduzierbar macht, ist dann ein Klacks.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Schon mal versucht den Netzwerk-Status zu testen, bevor einfach mal nen langes Nickerchen in den Code implementiert wird?
Klar, kann man auch machen - wenn man das Coden kann. Man kann es sich auch einfach machen, indem man in der systemd Service Unit `After=network-online.target` einbaut. Dann kümmert sich systemd um's Warten die Nebenläufigkeit der eigenen Units mit den anderen Units.

Und natürlich kannst _du_ für dich machen, was du willst. Nur ist es halt fragwürdig, legacy Methoden mit Nachdruck und ohne Grund zu propagieren und damit evtl. andere Nutzer von besseren, neueren, schöneren Methoden abhalten.

Gruß, noisefloor
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Johnes: Wenn es eine bekannte Ausnahme ist, bei der es in Ordnung ist die zu ignorieren, dann würde das Programm die ja ignorieren, damit die nicht im Log auftaucht. Die Logs sind ja für die Fälle mit denen man *nicht* gerechnet hat. Falls also etwas aus einem anderen Grund nicht funktioniert, den man noch nicht kennt, wird man den ohne die Fehlerinformation auch nicht kennenlernen, und kann das dann auch nicht beheben.

Gleiches für das UDP-Paket. Wenn das okay ist und man erwartet, dass keine Quittierung kommt, und das ist ja hier sogar ein ganz normaler Fall bei UDP, damit *muss* man rechnen. Das muss man dann auch nicht protokollieren wenn es einen nicht stört. Aber auch hier geht es wieder um die Fehler mit denen man nicht gerechnet hat.

Ich brauche den Netzwerkstatus nicht zu testen, denn ich weiss ja das mein Dienst von systemd erst gestartet wird, nachdem das Netzwerk-Target erreicht wurde, wenn ich das so konfiguriere. Das testen ersetzt ja auch nur das lange Nickerchen mehrere kleine in einer Schleife + Tests. Je weniger Verzögerung ich haben will zwischen „Netzwerk da“ und „Programm fängt richtig an“, desto öfter muss ich Testen. Ersetzt also Wartezeit durch Rechenzeit.

Will ich auf Deinem Osborne rumhacken? Eher nicht, ich mag lieber die 6502-Prozessorfamilie. Und ich schrob ja 8-Bit-Rechner *oder* DOS. Das schliesst sich ja mehr oder weniger aus, sofern man nicht so masochistisch ist einen 8086-Emulator für einen 8-Bit-Prozessor zu schreiben. Es dürfte deutlich langsamer als das Original werden, wenn man das beispielsweise auf einem Z80 mit 4 Mhz laufen lassen will, wo der originale IBM-PC mit 4,77 Mhz läuft.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
nezzcarth
User
Beiträge: 1634
Registriert: Samstag 16. April 2011, 12:47

Johnes hat geschrieben: Donnerstag 24. November 2022, 05:35 Ich hab jetzt nicht gelesen, er benötigt das Script immer im Hintergrund. Aber zeitgesteuerte Ausführung bzw. einmaliger Start an Punkt X funktioniert mit Cron eigentlich ziemlich gut.
Mag stimmen, von zeitgesteuerter Ausführung steht im Ausgangspost aber genau so wenig ;) Der Hauptzweck von Cron ist die periodische Ausführung. Für einmalige Sachen verwendet(e) man traditionell Atd.

Dazu kommt, dass @reboot und die anderen @… Shortcuts nicht Teil des Posix-Standards sind. Das sind nicht-standardisierte Erweiterungen, die, soweit ich weiß, auf Vixie-Cron zurückgehen und eher ein Behelf aus einer Zeit sind, als es eben noch nichts anderes gab. Gerade @reboot hat eigentlich auch nicht wirklich was mit dem zu tun, wozu Cron eigentlich gedacht ist. Das heißt jedenfalls erstens, dass es nicht gesagt ist, dass jede Implementierung das auch wirklich versteht (z.B. bei einigen kommerziellen Unixen der Fall). Und es ist, zweitens, insbesondere auch nicht gesagt – weil nicht spezifiziert – dass es dasselbe tut. Reboot kann sich auf den (Neus)tart des Systems oder auf den des Cron-Daemons beziehen.

So ganz verstehe ich auch nicht, warum du dich gegen die ganzen technischen Gründe so wehrst. Wenn du das verwenden möchtest, sei dir das ja unbenommen. Aber da es ja an eine andere Person als Empfehlung gerichtet war, ist es m.M.n. auch wichtig zu erklären, dass und warum man das eigentlich nicht mehr so macht. Ich finde, das hat auch mit "deprecated-Polizei" nichts zu tun.
Johnes
User
Beiträge: 7
Registriert: Mittwoch 23. November 2022, 19:58

at ist beim Pi meist nicht vorinstalliert.

cron nutze ich zudem für zyklische Backups mittels rsync. Daher, nutze ich eben crontab eben auch für einmalige Ausführungen einiger Dinge, ohne dafür eine Unit nutzen zu müssen.

Für den TE nochmal zusammen gefasst:

Code: Alles auswählen

crontab -e
@reboot   python3 /Pfad/zum/Python/script.py

Code: Alles auswählen

sudo systemctl edit --force --full dein_script_name.service

[Unit]
Description=Beschreibung für das Script
#Requires=network-online.target    # falls Netzwerk gebraucht wird
#Wants=network-online.target        # Kompatibilität für unterschiedliche OS-Versionsn
#After=network.target network-online.target

[Service]
Type=oneshot # wenn es nur einmal ausgeführt werden soll, alternativ "simple"
ExecStart=/usr/bin/python3 /Pfad/zum/Python/script.py
WorkingDirectory=/Pfad/zum/Python/
#user=pi   # welchen Nutzername nutzen? pi/root/dein_user

[Install]
WantedBy=multi-user.target
Die Unit sollte auch aktiviert werden:

Code: Alles auswählen

sudo systemctl enable dein_script_name.service
@nezzcarth:
VIelleicht willst du ja noch beschreiben, wie man mittels at ein Script beim Boot ausführt.

Oder wie wäre auch noch rc.local? Dann haben wir alles zusammen, was man so nutzen kann. Ob alt, veraltet oder state-of-art.

MfG
nezzcarth
User
Beiträge: 1634
Registriert: Samstag 16. April 2011, 12:47

Mir ist keine Implementation von At bekannt, die das ermöglicht. Ich habe das auf deine Aussage "einmaliger Start an Punkt X" hin angeführt, für den Fall, dass damit (auch) einmalige Zeitpunkte gemeint waren. Genau dafür ist Cron eben nicht geeignet.

rc.local ist ähnlich veraltet und sollte nicht mehr verwendet werden. Gegenwärtig wird das z.B. noch unter debian/raspbian intern über einen Kompatibilitätsmechanismus mittels systemd ausgeführt: https://www.freedesktop.org/software/sy ... rator.html
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

falls jemand die Unit übernehmen möchte: wenn man ein stehendes Netzwerk braucht reicht die Direktive `After=network-online.target`, der Rest ist nicht nötig.

`WorkingDirectory=/Pfad/zum/Python/` kann man machen - aber warum? Also warum soll man den Arbeitspfad auf ein Systemverzeichnis setzen (in dem das Binary des Python-Interpreters liegt)? Wenn das Skript Daten in eine Datei schreibt, dann sollte die eher woanders liegen, also z.B. `/var/log` oder ein Homeverzeichns.

Gruß, noisefloor
Antworten