Python Programm per Befehl beenden

  • 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:

  • Mittels subprocess hast du die Möglichkeit jeden Befehl abzusetzen wie in der Konsole auch.

    Ja, das weiß ich! Allerdings braucher ich dafür die PID, welche flexibel ist... kann ich die auch irgendwie mit subprocess (oder einem anderen Modul) bekommen?

    Natürlich mache ich Fehler :stumm:

  • 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
    1. import shlex
    2. import subprocess
    3. def programm_beenden():
    4. befehl = "pkill -f deinskript.py"
    5. cmd = shlex.split(befehl)
    6. subprocess.run(cmd)
  • Hallo,


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


    BTW: ich nutze kein MQTT, aber nach meinem Verständnsi der Doku wird `on_disconnect` nur aufgerufen, wenn der Client aktiv einen disconnect ausführt?


    Gruß, noisefloor

  • 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
    1. a = 1
    2. b = 2
    3. a + b
    4. raise TypeError
  • Code
    1. import os
    2. import signal
    3. 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
    1. a = 1
    2. b = 2
    3. a + b
    4. 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:

  • Hallo,

    Zitat

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

    `raise` löst manuell eine Excpetion aus - also das, was normalerweise nur durch Programm- oder Programmierfehler ausgelöst wird. Braucht man eigentlich eher selten.


    Gruß, noisefloor

  • 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-

  • 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-gui…-connections-python-mqtt/

    "Alles, was wir sind, ist Sand im Wind, Hoschi."

  • 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
    1. def on_disconnect3(client, userdata,rc):
    2.     try:
    3.         client.reconnect()
    4.     except:
    5.         #ist mir egal
    6.         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: