os.popen/os.system ausgabe direkt printen

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
ruiin
User
Beiträge: 20
Registriert: Mittwoch 11. April 2012, 16:31
Wohnort: Essen

Hi,

ich bau mir grad ein script um rsync auszuführen.

Doch leider versteckt mein Pythonscript die Ausgabe eines rsync-Kommandos. So möchte ich gerne eine Ausgabe von "rsync -v" endweder direkt ausgeben, so das jede Zeile in os.popen.readlines beim generieren ausgegeben wird, oder das ich die Zeile weiterverarbeiten kann. Um zb. einen Ladebalken zu bauen, der mir angibt wie lange es noch dauert.

wie kann ich so eine ausgabe direkt verarbeiten?

gruß und danke
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Mit subprocess ist das möglich.
the more they change the more they stay the same
Benutzeravatar
snafu
User
Beiträge: 6908
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Um zeilenweise die "Live-Ausgabe" eines Programms zu lesen, kann man für Python 2.x (wegen http://bugs.python.org/issue3907) wohl am Besten `readline()` verwenden:

Code: Alles auswählen

while True:
    line = programm_stdout.readline()
    if not line:
        break
    do_something(line.rstrip())
`.rstrip()` sorgt dafür, dass die Zeilenenden abgeschnitten werden. Eventuell ist dir das lieber. Beachte, dass ein `.strip()` (also ohne "r" davor) hierfür keine so gute Idee wäre, da dies auch mögliche Einrückungen am Anfang einer Zeile abschneidet. Insbesondere bei Textdateien mit Programmcode eher schlecht. ;)

Nichtsdestotrotz sei dir die Verwendung des schon genannten `subprocess`-Moduls ans Herz gelegt. `os.popen()` ist nämlich als deprecated markiert und wird daher bald aus Python rausgeschmissen.
ruiin
User
Beiträge: 20
Registriert: Mittwoch 11. April 2012, 16:31
Wohnort: Essen

funktioniert bei ping schon super.
Benutzeravatar
snafu
User
Beiträge: 6908
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Alternativ müsste übrigens auch folgendes gehen:

Code: Alles auswählen

for line in iter(stream.readline, ''):
    do_something(line)
Das führt `readline()` solange aus, bis es nichts mehr zu lesen gibt. `''` beschreibt eine leere Zeile, die nämlich das Streamende darstellt. Trifft `iter()` auf diese Darstellung, dann folgen keine weiteren Aufrufe mehr.

Wie gesagt: Alles nur Workarounds aufgrund des Bufferingsverhaltens beim Lesen von Pipes unter Python 2.x. Unter Python 3.x kannst du einfach `for line in stream:` sagen.
Antworten