subprocess, popen und Co.

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Leider klappt es nicht ganz mit der ermittlung ob der Prozess noch läuft oder nicht :(
Unter Python v2.2.1 auf Hosteurope (mit nachgerüstetem subprocess) ist process.poll() immer gleich "None" :(
Lokal bei mir mit Python 2.4.1 unter debian liefert poll mit normale Werte...

Wie kann ich noch feststellen, ob der subprocess beendet ist???

EDIT 1: Ach eine andere Variante ist einfach das versuchte kill ;)

Code: Alles auswählen

        try:
            os.kill( self.process.pid, signal.SIGQUIT )
        except OSError:
            # Process war schon beendet
            pass
        else:
            # Process mußte beendet werden
            self.killed = True
Die Variante funktioniert wiederum nur bei Hosteurope, weil dort eine Exception auftritt, falls der Prozess nicht mehr existiert... Hingegen gibt es bei mit lokal keine Exception...
Somit kann ich zwar einen Timeout setzten bzw. ausführen, aber ich weiß nicht ein Timeout überhaupt aufgetreten ist :( Das möchte ich aber gern wissen...

EDIT 2: Soeben ist mir eine etwas blöde Art eingefallen... Ich teste einfach die Ausführungszeit. Wenn diese gleich oder größer als der timeout ist, wurde der Prozess gekillt:

Code: Alles auswählen

class subprocess2(threading.Thread):
    """
    Allgemeine Klasse um subprocess mit einem Timeout zu vesehen.

    Da os.kill() nur unter Linux und Mac verfügbar ist, funktioniert das
    ganze nicht unter Windows :(

    Beispiel Aufruf:
    ---------------------------------------------------------
    import os, subprocess, threading, signal

    process = subprocess2( "top", "/", timeout = 2 )

    if process.killed == True:
        print "Timout erreicht! Prozess wurde gekillt."
    print "Exit-Status:", process.returncode
    print "Ausgaben:", process.out_data
    ---------------------------------------------------------
    """
    def __init__( self, command, cwd, timeout ):
        self.command    = command
        self.cwd        = cwd
        self.timeout    = timeout

        self.killed = False # Wird True, wenn der Process gekillt wurde
        self.out_data = "" # Darin werden die Ausgaben gespeichert

        threading.Thread.__init__(self)

        start_time = time.time()
        self.start()
        self.join( self.timeout )
        self.stop()
        duration_time = time.time() - start_time

        if duration_time >= timeout:
            # Die Ausführung brauchte zu lange, also wurde der Process
            # wahrscheinlich gekillt...
            self.killed = True

        # Rückgabewert verfügbar machen
        try:
            self.returncode = self.process.returncode
        except:
            self.returncode = -1

    def run(self):
        "Führt per subprocess den Befehl 'self.command' aus."
        self.process = subprocess.Popen(
                self.command,
                cwd     = self.cwd,
                shell   = True,
                stdout  = subprocess.PIPE,
                stderr  = subprocess.STDOUT
            )

        # Ausgaben speichern
        self.out_data = self.process.stdout.read()

    def stop( self ):
        try:
            os.kill( self.process.pid, signal.SIGQUIT )
        except OSError:
            # Process war schon beendet
            pass

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Das ganze hab ich nochmal aktualisiert, siehe:
http://www.python-forum.de/post-96164.html#96164
http://trac.pylucid.net/browser/trunk/p ... y?rev=1634

EDIT: Im neuen Thread gehts weiter: http://www.python-forum.de/topic-14301.html
EDIT2: Link aktualisiert.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten