Python Programm per Befehl beenden

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo zusammen,
    ich habe ein Problem mit einem meiner Programme:

    ich streame Daten über einen Mosquito MQTT-Broaker, der Server, auf dem der Broaker läuft, macht allerdings jede Nacht um 3 einen Restart, bei diesem restart bricht die Verbindung kurz ab. wenn der Broaker neu startet, schicken meine PIs die Daten munter weiter und lauschen dem Topic auch, allerdings "ignoriert" der Server deren existenz, da sie nicht mehr registriert sind. Ich wollte das Problem lösen, indem ich auf den PIs die Folgende Funktion nutze:

    Dadurch soll das Programm beendet werden, sobald die Verbindung unterbricht. (Es wird automatisch neu angestartet, sobald es nicht mehr läuft und erzeugt dann auch dioe Verbindung neu)

    Leider funktioniert das nicht... wenn ich statt sys.exit() beispielsweise print('Exit') schreibe, wird dieser Befehl ausgeführt.

    Also scheint sys.exit() nicht zu funktionieren.

    Ich weiß, dass sys.exit() eine Exception aufruft, und diese theoretisch noch abgefangen werden kann...

    Meine Frage wäre folgende: gibt es eine Möglichkeit, das Programm einfach umzuhauen? Also quasi ein dreistes  kill -9  in python aufzurufen?

    und ja, ich weiß dass man das eigentlich nicht machen soltle, und das man dem PI die möglichkeit nimmt, das Programm ordentlich zu beenden und und und, das müsst ihr mir nicht erzählen ;)

    Aber solch einen Befehl benötige ich momentan, ich kenne leider keinen...

    Vielen Dank schonmal!

    Natürlich mache ich Fehler :stumm:

    • Offizieller Beitrag

    Ja, das weiß ich! Allerdings braucher ich dafür die PID, welche flexibel ist...

    pkill braucht keine PID, nur den Prozessnamen und ein Signal kannst Du auch verwenden. Bleibt aber trotzdem ein Würgaround... :shy:

  • allerdings "ignoriert" der Server deren existenz, da sie nicht mehr registriert sind.

    Kann man das per Skript auch iwie prüfen, wie connection.ok=True o.ä?

    Wenn ja, dann wär mein Gedanke, bau das ganze mit einer while connection.ok Schleife auf, wenn die connection nicht mehr ok ist, da sie nicht mehr registeriert ist, fällst du aus der Schleife und das Programm beendet sich.

    Dein Skript lässt du via systemd starten, dh. es startet dir das Skript nach Beendigung automatisch wieder...die Option Restart=always sorgt dafür dass das Skript von allein wieder gestartet wird, gibt noch mehr Parameter, siehe hier

    #StartLimitIntervalSec=120

    #StartLimitBurst=4

    könnte man noch steuern ab wie vielen Fehlversuchen in welcher Zeit nicht mehr gestartet werden soll.

    EDIT: ansonsten wie hyle schon sagt, mit pkill kannst du dein Skript direkt ansprechen ala:

    Python
    import shlex
    import subprocess
    
    
    def programm_beenden():
        befehl = "pkill -f deinskript.py"
        cmd = shlex.split(befehl)
        subprocess.run(cmd)
  • Falls noch ein Programm gesucht wird zum starten/beenden von anderen Programmen. Ich bin Gestern über start-stop-daemon gestolpert. Bietet viele Möglichkeiten, aber ich kann nicht sagen ob es das Richtige für dich ist. Siehe man start-stop-daemon.

  • pkill braucht keine PID, nur den Prozessnamen und ein Signal kannst Du auch verwenden. Bleibt aber trotzdem ein Würgaround... :shy:

    perfekt, das wäre ne Option! Danke.


    Kann man das per Skript auch iwie prüfen, wie connection.ok=True o.ä?

    habe leider keine Funktion in der richtung gefunden...

    Aber ich könnte über den return Wert der publish Funktion arbeiten :/


    Dein Skript lässt du via systemd starten, dh. es startet dir das Skript nach Beendigung automatisch wieder...die Option

    Ich lasse es mit Monit neu starten, aber das Prinzip ist das selbe, ja :^^:

    was passiert, wenn du statt `sys.exit()` `raise SystemExit` ins Skript schreibst?

    Das habe ich noch nicht versucht, was macht die Funktion denn? Die kenne ich nicht!

    Warum?

    Ich schätze mal, weil das Jemand so eingestellt hat! Es ist nicht mein Server, ich kann ihn nur mit nutzen!

    kann der Broker keinen Befehl zum disconnecten der Clients senden? Das wäre a) sauberer und b) spart client-seitige Verrenkungen.

    Ja, das wäre gut! Allerdings ist auf dem Server leider ein QoS von 1 eingerichtet, und ich habe keine Möglichkeit, etwas am Server zu ändern...:no_sad:

    Natürlich mache ich Fehler :stumm:

  • Das habe ich noch nicht versucht, was macht die Funktion denn? Die kenne ich nicht!

    Das ist keine Funktion ansich sondern mit raise wirfst du selbst Exceptions, immer den Typ welchen du hinter raise schreibst.

    Eigentlich kein Fehler aber ich kann dennoch einen Fehler ausgeben lassen:

    Python
    a = 1
    b = 2
    
    a + b
    raise TypeError
  • Code
    import os
    import signal
    
    os.kill(os.getpid(),signal.SIGTERM)

    os.getpid() ist glaube ich genau das, was ich gesucht hatte! dann kann ich theoretisch mit
    subprocess.Popen('kill -9 '+str(os.getpid())) den Prozess gnadenlos vernichten!

    Habe es jetzt erstmal über den returnwert der publish Funktion versucht, wenn das nicht funktioniert, versuche ich das mal!!

    Das ist keine Funktion ansich sondern mit raise wirfst du selbst Exceptions, immer den Typ welchen du hinter raise schreibst.

    Eigentlich kein Fehler aber ich kann dennoch einen Fehler ausgeben lassen:

    Python
    a = 1
    b = 2
    
    a + b
    raise TypeError

    dann ist es ja quasi das selbe... sys.exit() ruft ja auch nur ne excetion auf...


    Also vielen Dank an alle, ich denke mal ich kann aus all dem hier eine Funktionierende Lösung bauen!
    Ich geb euch bescheid, wenn ich was gefunden habe was funktioniert, da der Server nur einmal am Tag restartet, habe ich allerdings nur einen Versuch täglich ;)

    Vielen Dank an Alle, ihr wart ne Große Hilfe :danke_ATDE::danke_ATDE::danke_ATDE:

    Natürlich mache ich Fehler :stumm:

  • Ich versteh' nach wie vor nicht, warum die clients nicht einfach einen reconnect machen.

    Ist doch eine Standard-Situation jeder client Server Anwendung, dass die Verbindung, mal länger, mal kürzer, unterbrochen bzw. nicht verfügbar ist.

    Aber vielleicht kann/mag das mal einer erklären, warum das hier nicht möglich ist und sich der Server-Prozess per kill (was an sich schon ein Witz ist) selbst abschiessen muss.

    Sorry, wenn ich da so direkt werde, aber im Vergleich zu praktisch allen anderen Threads, die ich hier im Forum gelesen habe, sticht dieser dermassen hervor und hinterlässt bei mir den Eindruck, dass hier nur Dilettanten am Werk sind.

    Ich kann's irgendwie nicht glauben, dass das von denselben Leuten verfasst wurde, von denen tausende, meiner Meinung nach qualitativ hochwertige Beiträge stammen.

    Ich bin verwirrt ...

    cu,

    -ds-

    • Offizieller Beitrag

    Ich versteh' nach wie vor nicht, warum die clients nicht einfach einen reconnect machen.

    Ist doch eine Standard-Situation jeder client Server Anwendung, dass die Verbindung, mal länger, mal kürzer, unterbrochen bzw. nicht verfügbar ist.

    Sehe ich auch so! Eine kurze Suche ergab das hier: http://www.steves-internet-guide.com/client-connections-python-mqtt/

  • Ich versteh' nach wie vor nicht, warum die clients nicht einfach einen reconnect machen.

    das verstehe ich auch nicht, da sind wir schon zu zweit!

    aber

    client.loop_start()

    oder

    client.loop_forever()

    machen ihren job leider nicht und nehmen den disconnect einfach hin ohne den reconnect zu versuchen.

    befor du mir damit kommst:

    Python
    def on_disconnect3(client, userdata,rc):
        try:
            client.reconnect()
        except:
            #ist mir egal
            pass

    Funktioniert leider auch nicht!

    Das Programm abzuschießen und neu zu starten schien mir für den Übergang eine gute Idee zu sein, deshalb auch der Titel

    "Python Programm per Befehl beenden"

    und nicht

    "erklärt mir MQTT, ich weiß nicht was das ist."

    hätte ich probleme damit, MQTT zu verstehen, hätte ich die Frage wahrscheinlich anders gestellt?

    Ich kann leider nicht in die Server Files schauen, wäre das mein Server, könnte ich euch auch deutlich mehr Informationen geben, kann ich aber leider nicht, da ich keinen Einblick in den Server habe und keine permissions etwas zu ändern.

    Ich kann ihn so ntzen wie er ist, oder ich kann ihn garnicjht nutzen und wenn er nicht reconnectet, oder einmal täglich restartet oder was weiß ich macht, dann kann ich daran nichts ändern.

    Wäre ja schön und gut wenn immer alles läuft wie im Kinderbuch, aber wenn ich eine Frage schon spezifisch stelle, dann habe ich mir wahrscheinlich edanken darüber gemacht, warum ich diese Frage so stelle?!

    Und ne Info am Rande: Ich habe diesen Beitrag bewusst als erledigt markiert, weil ich hier genügend hilfreiche Informationen bekommen habe, um das Problem mit sicherheit auf irgendeine Weise lösen zu können, was dieses permanente Beschweren über Gott und die Welt soll verstehe ich nicht so ganz dreamshader aber wenn es dir zu blöd ist, lies es einfach nicht. Ich habe ne Frage gestellt, ich habe ne Menge hilfreiche Antworten bekommen, ich finde das toll freu dich drüber oder lass es, aber verteil nicht unnötig Beleidigungen, das wäre sehr nett!

    Natürlich mache ich Fehler :stumm:

Jetzt mitmachen!

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