Überprüfen ob Prozess läuft

  • Hallo zusammen,


    innerhalb eines Skriptes möchte ich überprüfen, ob ein anderes Skript läuft. Dazu habe ich mir folgendes Python-Skript programmiert. Es funktioniert, allerdings ist das bestimmt nicht die "saubere" Lösung. Hat jemand noch eine andere Idee, wie ich das sonst machen könnte?


    Vielen Dank und viele Grüße


    whitechristmas

  • Hallo,


    das ist relativ unpythonisch, weil du einfach nur einen Python-Wrapper für eine Shellbefehl schreibst. Das Umleiten in eine Datei ist eigentlich auch Quatsch, weil die direkt mit der Ausgabe von subprocess arbeiten kannst bzw. darüber iterieren.

    Und wenn du schon über die Datei iterierst kannst du an der Stelle direkt den Vergleich machen anstatt alles in einen String zu schreiben und dann erst zu vergleichen.

    `Popen` braucht man eigentlich nur, wenn man später noch Kontrolle über den subprocess braucht - brauchst du aber nicht.

    Dateien öffnet man mit dem with-Statement, dann werden sie auch automatisch geschlossen.


    Was du vielleicht nutzen möchtest: das psutil Modul. Da gibt es auch ein fertiges Rezept für das, was du suchst.


    Wie wird `kamara.py` gestartet? Wenn du es über eine systemd Service Unit machst hast du darüber alle Infos und kannst das Skript wenn nötig auch automatisch neu starten lassen.

    Gruß, noisefloor

  • Hallo noisefoor,


    das "fertige Rezept" funktioniert prinzipiell. Allerdings ist das Ergebnis folgendes:


    Der Prozess sieht so aus (ps -aux | grep python3):

    pi 27515 29.6 4.5 115556 39896 pts/2 Ssl+ 14:02 0:28 /usr/bin/python3 /home/pi/python/kamera/kamera.py


    Als Prozessname muss man "/usr/bin/python3" angeben.


    Ergebnis:

    [psutil.Process(pid=27515, name='python3', started='14:02:09'), psutil.Process(pid=28058, name='python3', started='14:11:16'), psutil.Process(pid=28170, name='python3', started='14:13:43')]


    Was, wenn mehrer Python-Prozesse, wie hier zu sehen, laufen?


    Vielen Dank und viele Grüße


    whitechristmas


    PS: Wie kann ich mit meiner Loesung ohne das Schreiben in eine Datei arbeiten?

  • Hallo,


    ist in so fern auch richtig, als das der Prozess ja der P3 Interpreter ist und nicht das Skript. Das wird ja "nur" im Prozess ausgeführt.


    Lösung: du musst gegen `p.info['cmdline'][1] vergleichen. `p.info['cmdline']` sollte so aussehen: `['/usr/bin/python3', 'name_des_skripts']`, also ist das 2. Element der Liste der Skriptname. Diese Lösung habe ich hier gefunden: Link.


    Wenn man sich damit beschäftigt macht es denke ich auch Sinn, sich mal alle Methoden der `Process` Klasse anzuschauen, weil man da einen ganze Menge Infos raus ziehen kann: Doku.


    Gruß, noisefloor

  • Hallo noisefloor,


    mein Skript sieht jetzt so aus:


    Das Ergebnis ist folgendermaßen:

    Traceback (most recent call last):

    File "test_prozess.py", line 17, in <module>

    print(find_procs_by_name("kamera.py"))

    File "test_prozess.py", line 12, in find_procs_by_name

    p.info['/usr/bin/python3', name] and p.info['cmdline'][1] == name:

    KeyError: ('/usr/bin/python3', 'kamera.py')


    Was mache ich falsch?


    Vielen Dank und viele Grüße


    whitechristmas



    ------------------

    (program exited with code: 1)

    Press return to continue

  • Hi, so sieht das bei mir aus in meinen Skripten:

    Python
    def check_process():
        processliste = [p.cmdline() for p in process_iter() if "python" in p.name()]
        return sum([p.count(sys.argv[0]) for p in processliste])
    
    laufende_prozesse = check_process()
        if laufende_prozesse > 1:
            print("EXIT aufgrund laufender Prozesse")
            sys.exit()
  • Hallo,


    whitechristmas: bei so was ist es immer hilfreich, sich ein paar print-Befehle einzubauen, wenn man den Fehler so nicht sieht. Du versuchst halt, auf eine Schlüssel eines Dict zuzugreifen, den es nicht gibt.


    Da ganze ist aber auch ein wenig zu komplex, wenn du gezielt nach einem Skript suchst. Das sollte funktionieren:


    Python
    def find_process(name):
        for p in psutil.process_iter(attrs=["name", "exe", "cmdline"]):
             if len(p.info['cmdline']) == 2 and p.info['cmdline'][1]==name:
                print('found {} with process {}'.format(name, p.info['cmdline'][0]))


    Gruß, noisefloor