subprocess und newline

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
Shadowxy1
User
Beiträge: 5
Registriert: Mittwoch 8. Februar 2006, 16:06

Hallo Zusammen,

habe da mal eine Frage zum folgenden Kontext:

Es handelt sich um ein Linuxsystem und Python 2.7.3 ist installiert.
Kleines Beispiel mit partclone.

Code: Alles auswählen

import subprocess

sub = subprocess.Popen(['partclone.chkimg', '-B', '-s', 'sda2.reiserfs'], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

for line in iter(sub.stderr.readline, ""):
    print line
Soweit ich weiß gibt "sub.stderr.readline" nur etwas zurück wenn eine "newline" kommt, ansonsten wartet es. Nun gibt es Programme, die den Status aber immer wieder in die selbe Zeile ausgeben und somit kein "newline" kommt. Erst bei Beendigung des Prozesse wird dann der Status ausgegeben. Kann man dieses irgendwie umgehen?


PS: Habe den suprocess editiert

Gruss shadowxy1
Zuletzt geändert von Shadowxy1 am Montag 13. Mai 2013, 12:05, insgesamt 2-mal geändert.
BlackJack

@Shadowxy1: Ausser nicht `readline()` zu verwenden, würde sagen Nein.

``shell=True`` sollte man übrigens vermeiden, sonst hat man die gleichen Probleme die man mit `os.system()` auch hat. Und unter anderem um die loszuwerden gibt es ja das `subprocess`-Modul.
Shadowxy1
User
Beiträge: 5
Registriert: Mittwoch 8. Februar 2006, 16:06

Was soll ich denn verwenden, wenn nicht readline? Bzw. gibt es vielleicht noch andere Möglichkeiten den Fortschritt zu erfragen?
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Es gibt ja schon noch ein paar andere Methoden die man nutzen kann, irgendwas sagt mir dass die auch irgendwo dokumentiert sind.
Shadowxy1
User
Beiträge: 5
Registriert: Mittwoch 8. Februar 2006, 16:06

Kannst du mir mal ein paar Hinweise geben nach was man da soo gucken kann?!
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Angeblich gibt es da so eine Dokumentation zu Python ... ;-)
Das Leben ist wie ein Tennisball.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Och kommt schon, das muss nicht sein.

`stderr` und `stdout` sind File-like Objekte: http://docs.python.org/2/library/stdtyp ... le-objects, ich wuerde es mit `read` versuchen.

Dann gibt es noch ein Problem: Wenn du `stdout` und `stderr` umleitest, solltest du auch beide auslesen, sonst kann es Probleme geben.
Shadowxy1
User
Beiträge: 5
Registriert: Mittwoch 8. Februar 2006, 16:06

Erstmal Danke an cofi, dass du mir wenigstens versuchst zu helfen :)

Die Python Doku ist groß und ohne sinnige Hinweise gleicht es einem Suchen der Nadel im Heuhaufen.

Aber zum Thema:

Ich bin mir noch nicht ganz sicher ob ihr genau wisst was ich meine. Also versuch ich es nochmal darzustellen:

Ich habe eine GUI. Diese GUI soll nun den Fortschritt eine Prozesse anzeigen, den ich mit einem subprozess starte.
In dem subprozess wird zum Beispiel ein Image mit Hilfe von partclone erstellt. Es können auch andere Dinge sein, wie ein Image zippen mit 7zip.

Wenn ich zum Beispiel den Befehl "partclone.chkimg -B -s sda2.reiserfs" im Terminal ausführe, wird der Fortschritt den ich haben will immer in der selben Zeile angezeigt, also die Zeile nur refresht.

terminal zeile 100: 0%
terminal zeile 100: 1%

Ich glaube mit Steuerzeichen sieht es dann so aus: \r0%\r1%\r2% usw.

Damit kommt aber readline und ich glaub auch read nicht zurecht, weil immer die selber Zeile refresht wird und nicht eine neue Zeile geschrieben wird.
Wenn die ausgabe Zeilenweise wäre, würde es funktionieren.

terminal zeile 100: 0%
terminal zeile 101: 1%

Irgendwann ist das Erstellen des Images abgeschlossen und dann bekomme ich die die 100% zurück.

terminal zeile 100: 100%
terminal zeile 101: successful

Aber alles was dazwischen passiert, also von 1%-99%, wird nichts zurückgegeben. Und somit kann ich keinen Fortschritt in der GUI anzeigen außer 0% und 100% :)

Die Frage ist eben wie ich an die Zwischenschritte herankomme.

Gruß shadowxy1
BlackJack

@Shadowxy1: Da kommst Du mit der `read()`-Methode dran. Wobei Du entweder byteweise lesen musst, oder in grösseren Blöcken und Du musst Dich um das zerlegen an den '\r'-Zeichen selber kümmern, beziehungsweise um das Zusammensetzen wenn Du byteweise liest.
Shadowxy1
User
Beiträge: 5
Registriert: Mittwoch 8. Februar 2006, 16:06

Hallo BlackJack,

das war der Hinweis den ich gebraucht habe. Ich habe read() immer ohne das byteweise lesen genutzt, darum hat er immer auf EOF gewartet.

Vielen Dank

Gruß shadowxy1
Antworten