Position von 'trap' im Script

L I V E Stammtisch ab 20:30 Uhr im Chat
  • Hallo zusammen.

    Ich habe mir für die Adventszeit einen kleinen LED-Adventskranz mit dem Pi gebastelt. Das Shellscript prüft dabei alle 10 Sekunden das Datum und schaltet je nach Datum 1, 2, 3 oder 4 LEDs an.

    Um bei Abbruch oder Stopp des Programms ordentlich aufzuräumen habe ich eine Funktion cleanup() eingefügt, die von trap aufgerufen wird (siehe Quelltext). Nun ist mir aufgefallen, dass es einen Unterschied macht, an welcher Stelle trap im Quelltext steht. Mir ist nicht ganz klar warum das so ist. Vielleicht kann mir das jemand von euch erklären.

    Hier der Quelltext, welcher wie gewünscht funktioniert:

    In diesem Fall steht das Kommando trap vor der while-Schleife. Stoppe ich das Programm mit Strg+C wird das Programm beendet und alle LEDs erlöschen. Die Funktion cleanup() wird ordnungsgemäß ausgeführt.

    Im folgenden Beispiel folgt das Kommando trap auf die while-Schleife. In diesem Fall bricht Strg+C zwar das Programm ab, doch wird die Funktion cleanup() nicht ausgeführt. Könnt ihr mir erklären warum das so ist?

    Vielen Dank für eure Hilfe.

    MfG
    Tronde

  • Hi,
    afaik muss der trap vor die Hauptschleife, sonst wird der nie ausgeführt ...

    Aber mal was anderes: ich will Dir nicht zu nahe treten, aber alle 10 Sekunden das Datum abzufragen um festzustellen, ob wir schon den zweiten oder dritten Advent haben, ist ein Programmierstil, den Du Dir gar nicht erst angewöhnen solltest.
    Spätestens nach der ersten Abfrage weisst Du, wie lange sich der script schlafen legen kann ...


    cu,
    -ds-

  • Deine Schleife ist eine Endlosschleife und der Code nach ihr wird niemals ausgeführt. Somit wird in der zweiten Variante, wo der trap nach der Schleife gesetzt nie ausgeführt und somit auch keine Spezialbehandlung von CTRL C aktiviert.

  • Hallo und Danke für eure Erklärung.


    Aber mal was anderes: ich will Dir nicht zu nahe treten, aber alle 10 Sekunden das Datum abzufragen um festzustellen, ob wir schon den zweiten oder dritten Advent haben, ist ein Programmierstil, den Du Dir gar nicht erst angewöhnen solltest.
    Spätestens nach der ersten Abfrage weisst Du, wie lange sich der script schlafen legen kann ...

    Ja, du hast recht. Das war quick&dirty. Ich prüfe das Datum jetzt nur noch alle 86400 Sekunden, also einmal am Tag.

    MfG
    Tronde

  • Wieso erstellst du dafür nicht einfach ein Crontab Eintrag um es Sonntags um Mitternacht auszuführen :huh:

    Code
    01 0 * 11,12 0    /bin/bash /path/to/Advent.sh

    Damit wird das Script jeden Sonntag um 00:01 Uhr, im 11. und 12. Monat ausgeführt. Somit brauchst du auch keine while Schleife mehr usw..

    Und noch ein Tip zu deinem Script: Du setzt zwar $date aber verwendest es nicht in der ersten if :-/

    Spoiler anzeigen

  • Und noch ein Tip zu deinem Script: Du setzt zwar $date aber verwendest es nicht in der ersten if :-/

    Danke für den Tipp, dass habe ich glatt übersehen.

    So ganz klappt das mit trap noch nicht so, wie ich mir das vorgestellt habe. In meinem Script steht:

    Code
    trap cleanup INT TERM EXIT


    Führe ich mein Script jetzt wie folgt im Terminal aus, kann ich es mittels Strg+C stoppen.

    Code
    pi@raspberrypi ~ $ ./advent.sh

    Nun habe ich es bei Aufruf gleich in den Background geschickt und versucht es mittels SIGTERM zu beenden:

    Code
    pi@raspberrypi ~ $ ./advent.sh &
    [1] 5687
    pi@raspberrypi ~ $ sudo kill -15 5687

    Hierbei wird die Funktion cleanup() jedoch nicht ausgeführt, denn die LED bleibt an. Könnt ihr mir sagen was ich falsch mache?

    MfG
    Tronde

  • Hi,

    also den kill kannst Du, so wie es aussieht, wohl nicht per trap abfangen ...
    Der normale Weg, den script zu beenden wäre sowieso kill <process> ... also ein SIGTERM.
    So wird das auch beim shutdown gemacht.
    Aber das sollte funktionieren ...
    cu,
    -ds-

  • Das klappt leider auch nicht. Ich glaube, dass es der kill-Befehl nicht schafft das Script zu beenden.

    Code
    pi@raspberrypi ~ $ ./advent.sh &
    [1] 5875
    pi@raspberrypi ~ $ sudo kill 5875
    pi@raspberrypi ~ $ ps -ef | grep advent.sh 
    pi        5875  5802  0 21:15 pts/3    00:00:00 /bin/bash ./advent.sh
    pi        5892  5802  0 21:15 pts/3    00:00:00 grep --color=auto advent.sh
    pi@raspberrypi ~ $

    Die sanfte Tour zieht irgendwie nicht. :s

    Gruß
    Tronde

  • Hm ...
    also nach dem Schema:


    klappts:

    Code
    pi@raspberrypi ~ $ ./lala.sh &
    [1] 29179
    pi@raspberrypi ~ $ kill 29179
    pi@raspberrypi ~ $ hulle
    
    
    [1]+  Done                    ./lala.sh
    pi@raspberrypi ~ $

    cu,
    -ds-

  • Hallo dreamshader,

    der Beispielcode aus deinem letzten Post funktioniert auf meinem Pi wie erwartet. Ich habe den trap-Code in meinem Script noch einmal wie folgt angepasst. Es lässt sich jedoch weiterhin nicht durch kill beenden.

    Hast du oder jemand anders noch eine Idee woran das liegt?

    VG
    Tronde

  • Warum der kill nicht geht? Das kann ich Dir sagen ... der script steht im sleep ... und da kommt das SIGTERM nicht durch.
    das kannst Du spasshalber bei meinem Miniteil mal austesten. Mach den sleep mal mit 30 und dann ruf das sript im BG auf ... dann schick den kill ... es dauert dann knapp 30 Sekunden, bis er sich beendet ;) ...

    cu,
    -ds-

  • Genauso ist es ! See also http://riccomini.name/posts/linux/20…ses-linux-bash/

    Folgendes funktioniert:

    Code
    kill -- -pid

    wobei pid "My pid" ist.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!