1. #1
    Avatar von DMW007
    Registriert seit
    15.11.2011
    Beiträge
    6.080
    Thanked 9.118 Times in 2.995 Posts
    Blog Entries
    5

    Standard

    Guten Abend,

    ich versuche ein Shell-Skript nach dem Booten des Kernels auszuführen. Laut Dokumentation soll systemd.run eine Systemd-Unit erzeugen und nach dem Booten automatisch ausführen. In der cmdline.txt eine Raspberry Pi 4 mit Raspberry Pi OS 11 Minimal habe ich dazu folgendes eingetragen:
    Code:
    console=serial0,115200 console=tty1 root=PARTUUID=d2b047ad-02 rootfstype=ext4 fsck.repair=no rootwait systemd.run=/boot/my_init.sh systemd.run_success_action=reboot
    Durch systemd.run_success_action will ich verhindern, dass der Pi automatisch herunter fährt. Statt reboot habe ich auch none angegeben, was laut systemd-run-generator Dokumentation bewirken soll, dass der Pi danach nichts macht - also das Skript ausführen und ganz normal starten, ohne Herunterfahren/Neu starten. Unabhängig davon fährt sich der Pi herunter. Ich habe den Boot-Prozess gefilmt, konnte dabei keine Fehler feststellen. Unmittelbar bevor der Bildschirm abschaltet, erscheint eine Meldung, dass er einen Dateisystem-Check startet. Testweise habe ich fsck.repair daher ebenfalls mal deaktiviert, ebenfalls ohne Ergebnis.



    Der Reboot wird erst durchgeführt, wenn ich systemd.run_failure_action=reboot setze. Es läuft also irgendwas mit dem Skript schief, ich finde aber keinen Hinweis was genau. In den Logs (nach dem Entfernen der Kernelparameter und dem erneuten Starten) ist auch nichts zu finden. Um auszuschließen, dass es etwas mit dem Skript zutun hat, habe ich dort nur 0 als erfolgreichen Exitcode ausgegeben:
    Code:
    #!/bin/bash
    exit 0
    Selbst das funktioniert seltsamerweise nicht, der Pi wird immer noch automatisch heruntergefahren. Jemand eine Idee?

  2. The Following User Says Thank You to DMW007 For This Useful Post:

    Hase (10.01.2022)

  3. #2
    Avatar von DMW007
    Registriert seit
    15.11.2011
    Beiträge
    6.080
    Thanked 9.118 Times in 2.995 Posts
    Blog Entries
    5

    Standard

    Es hat sich herausgestellt, dass es an einem sehr dummen Fehler liegt: Ich war unter Windows statt Linux unterwegs und hatte nicht auf dem Schirm, dass dort ja nicht LF (\n) wie unter Linux/Unix üblich verwendet wird. Sondern CR LF (\r\n), also einmal an den Anfang der Zeile und erst dann in die nächste Zeile. Linux beschwert sich daher, dass ein unerwartetes \r vor den Umbrüchen vorhanden ist.

    Nachdem ich im Shell-Skript nur LF verwende, lässt es sich ausführen und es wird nach dem Start aufgerufen. Für den praktischen Einsatz macht dieses POC-Szenario natürlich wenig Sinn. Man sollte im Skript die Kernelparameter entfernen:
    Code:
    sed -i 's| systemd.run.*||g' /boot/cmdline.txt
    Ansonsten wird das Skript bei jedem Start aufgerufen. So geschieht dies nur beim ersten Start, ab dem zweiten sind die systemd.run Parameter in der cmdline.txt nicht mehr gesetzt.

    Natürlich gibt es auch andere Ansätze. Der wohl generischste ist, den init Parameter des Kernels zu überschreiben. Hat den Vorteil, dass dies auch auf Systemen ohne Systemd funktioniert. Zwar ist Systemd mittlerweile auf vielen Distributionen das Standard-Initsystem. Aber es gibt auch welche die bewusst auf was anderes setzen, z.B. Alpine Linux. Im Gegensatz zu systemd.run ist das etwas aufwändiger und man muss sich händisch um ein paar Sachen kümmern, wie z.B. das Ein- und Aushängen der Datenträger. Da Debian (und damit auch das Raspberry Pi OS) vor längerem zu Systemd gewechselt sind, würde ich den einfacheren Ansatz bevorzugen, sofern nichts konkretes dagegen spricht.

Diese Seite nutzt Cookies, um das Nutzererlebnis zu verbessern. Klicken Sie hier, um das Cookie-Tracking zu deaktivieren.