Fortschrittsmeldung aus einem Teilprozess erhalten

Ich möchte ein Programm starten, das mehrere Minuten benötigt. Während dieser Zeit möchte ich die Fortschrittsmeldung des Programms lesen (die auf dem Stdout gedruckt wird). Das Problem ist, dass ich keinen Weg finden kann, seine Ausgabe während seines Laufes zu lesen.

Die einzige Funktion, die ich gefunden habe, um die Ausgabe eines Programms Popen.communicate() ist Popen.communicate() , aber diese Methode wartet, bis der Prozess beendet ist. So ist es unmöglich, den Fortschritt zu machen und für den Benutzer in einer speziell formatierten Weise sichtbar zu machen.

  • Java-Äquivalent von Python repr ()?
  • Batch konvertieren .py (Textdateien) zu .pdf auf osx
  • Wie man einen Fehler meldet, wenn ein Element nacheinander in einer Liste von Listen fehlt
  • Unterprozeß Fernbefehlsausführung in python
  • Migration kollidiert mit forms.py
  • Gibt es eine Möglichkeit zu wissen, ob ein Unicode-String ein beliebiges chinesisch / japanisches Zeichen in Python enthält?
  • Ist es möglich, dies anders zu machen?

    Wenn ich den Prozess mit subprocess.popen mit meinem Skript aussehe, sehe ich die Ausgabe des Programms auf dem Bildschirm. Ist es möglich, es zu verbergen? (Ubuntu 10.10, normales Terminal)

  • Wie kann ich den Python-Speicherfehler debuggen?
  • Wie entsteht ein benutzerdefiniertes Formular in Django?
  • SQLAlchemy StaleDataError beim Löschen von über ORM eingefügten Elementen sqlalchemy.orm.exc.StaleDataError
  • Schmutzige Felder in django
  • Installiere neue regex-Modul mit setup.py
  • Interaktives Matplotlib-Plot mit zwei Schiebereglern
  • 3 Solutions collect form web for “Fortschrittsmeldung aus einem Teilprozess erhalten”

    Einfacher ist, Popen mit dem Schlüsselwort argument stdout=subprocess.PIPE aufzurufen.

     p = subprocess.Popen(["ls"], stdout=subprocess.PIPE) while True: line = p.stdout.readline() if not line: break print line 

    Um dies in Aktion zu sehen, hier sind zwei Beispielskripts. Machen Sie sie beide im selben Verzeichnis und führen Sie python superprint.py

    Printandwait.py:

     import time import sys print 10 sys.stdout.flush() time.sleep(10) print 20 sys.stdout.flush() 

    Superprint.py:

     import subprocess import sys p = subprocess.Popen(["python printandwait.py"], shell=True, stdout=subprocess.PIPE) while True: print "Looping" line = p.stdout.readline() if not line: break print line.strip() sys.stdout.flush() 

    Sie können eine Abfrage über den Status Ihres Unterprozesses durchführen und Zeilen ausgeben.

     p = subprocess.Popen('ls;sleep 10', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) rc = p.poll() while rc != 0: while True: line = p.stdout.readline() if not line: break print line rc = p.poll() assert rc == 0 

    Es ist sicherlich möglich: mein Paket python-gnupg tut genau das, python-gnupg gpg (Gnu Privacy Guard) unter einem Teilprozess. Im allgemeinen Fall müssen Sie subprocess.PIPE für den Teilprozess stdout und stderr angeben; Dann erstellen Sie zwei separate Threads, die den Unterprozess stdout und stderr lesen, wo immer Sie wollen.

    Im Falle von python-gnupg werden Statusmeldungen von gpg gelesen und python-gnupg , während der gpg Prozess läuft (nicht warten bis es fertig ist).

    Grundsätzlich ist Pseudocode

     process = subprocess.Popen(..., stdout=subprocess.PIPE, stderr=subprocess.PIPE) stderr = process.stderr rr = threading.Thread(target=response_reader_func, args=(process.stderr,)) rr.setDaemon(True) rr.start() dr = threading.Thread(target=data_reader_func, args=(process.stdout,)) dr.setDaemon(True) dr.start() dr.join() rr.join() process.wait() 

    Die Leser-Funktionen sind in der Regel Methoden einer umschließenden Klasse, die die richtige Sache auf das, was sie lesen (in Ihrem Fall, Aktualisierung Fortschritte Informationen in irgendeiner Weise) zu tun.

    Python ist die beste Programmiersprache der Welt.