os.popen() bzw. commands.getoutput()

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.
hiroki
User
Beiträge: 2
Registriert: Mittwoch 3. März 2004, 17:23
Wohnort: ~/
Kontaktdaten:

os.popen() bzw. commands.getoutput()

Beitragvon hiroki » Sonntag 7. März 2004, 14:59

Hi!

Ich hab eine Frage bezüglich der beiden oben genannten Befehle.
Und zwar, ich muss mittels eines der beiden Befehle popen() bzw. getoutput() ein Programm ausführen. Dieses Programm jedoch läuft sehr lange (es ist ein programm zum encoden).
Ich möchte mit Python nun dieses Programm immer wieder ausführen für alle Dateien im Verzeichnis. Soweit kein Problem.

Mein Problem / Meine Frage setzt bei der Ausgabe dieses encoder-Programms an. Ich habe schon diverse Befehle ausprobiert.

Ich möchte, dass wenn der Encoder aufgerufen wird die Ausgabe des Programms auch auf dem Bildschirm erscheint, und zwar sofort! Im Moment gibt Python den Anfang der Ausgabe aus, und erst wenn das Programm terminiert wird die restliche Ausgabe auf den Bildschirm geschrieben. Ich weiß jedoch, dass das Programm ständig eine Fortschrittsanzeige aktualisiert, die wird jedoch erst angezeigt wenn das Programm sowieso beendet ist. Wie kann ich nun machen, dass der Fortschritt mir auch in python sofort ohne Pufferung o.ä. angezeigt wird?

Code: Alles auswählen

#!/usr/bin/env python

import glob, time, os, commands

if __name__ == "__main__":
        log = open("realcap.log", 'w')
        encoder = "mencoder -ovc lavc -lavcopts vcodec=mpeg4 -oac mp3lame -o %s %s"
        filelist = glob.glob("ITC2*.rm")
        urllist = []
        print "The following RealMedia files were found:"
        print " ".join(filelist), "\n"
        print time.ctime(), "\tStarted capturing of %d RealMedia files" % len(filelist)
        print >> log, time.ctime(), "\tStarted capturing of %d RealMedia files" % len(filelist)
        for file in filelist:
                f = open(file, 'r')
                url = f.readline()
                urllist += [url]
                f.close()
        print "".join(urllist)
        for url in urllist:
                url = url.replace("\r\n", "")
                filename = url.split("?")[0]
                filename = "cap_" + filename[filename.rfind("/")+1:] + ".avi"
                command = encoder % (filename, url)
                print "Fetching RealVideo Stream from:", url
                print time.ctime(), "\tCapturing", filename, "started"
                print >> log, time.ctime(), "\tCapturing", filename, "started"
                print os.popen(command).read()
                #for line in os.popen(command).readlines():
                #       print line,
                #print commands.getoutput(command)
                #print "".join(os.popen(command).readlines())
                print >> log, time.ctime(), "\tCapturing", filename, "finished"
                print time.ctime(), "\tCapturing", filename, "finished"

        print >> log, time.ctime(), "\tFinished capture process"
        print time.ctime(), "\tFinished capture process"
        log.close()


Das ist das Programm so wie es jetzt aussieht. Die Möglichkeiten wie ich versucht habe es auszugeben, damit die Ausgabe nicht verzögert erfolgt sind auskmmentiert, also folgende Zeilen aus obigem Programmtext:

Code: Alles auswählen

                print os.popen(command).read()
                #for line in os.popen(command).readlines():
                #       print line,
                #print commands.getoutput(command)
                #print "".join(os.popen(command).readlines())


Danke schonmal für Eure Hilfe,

hiroki
hiroki
User
Beiträge: 2
Registriert: Mittwoch 3. März 2004, 17:23
Wohnort: ~/
Kontaktdaten:

Beitragvon hiroki » Sonntag 7. März 2004, 16:45

Ich hab ein einfaches Beispiel für mein Problem gefunden, also müsst Ihr Euch nicht oben durch den Quelltext "quälen" ;)

Code: Alles auswählen

print "".join(os.popen("ping google.de -c 5").readlines())


hier hätte ich also gerne, dass nach und nach (wie beim echten ping) jede Zeile ausgegeben wird. Was er jedoch in Wirklichkeit tut ist auf das Ende des Programmlaufs zu warten und dann alles auf einmal auszugeben.

Wie kann ich das verhindern? -> Also eine "Echtzeit"-Ansicht bekommen?

danke,

Hiroki

PS: Ach ja, ich weiß, dass es os.system() gibt, jedoch möchte ich auch die Ausgabe auswerten können :/ Dadurch entsteht das Problem ja überhaupt erst...
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Beitragvon Milan » Sonntag 7. März 2004, 18:20

Hi. Aus meinen Erfahrungen dazu ist es nicht möglich, die Ausgabe in Echtzeit abzupassen. Auf jeden Fall nicht mit commands.getoutput und ich glaube auch nicht mit Versionen von popen. Hier bin ich mir jedoch nicht sicher. Ich glaube, dazu mal was in der Docu gelesen zu haben, aber weiß es nicht mehr. Mit den Funtionen popen-popen4 denk ich mal nicht. Es ist aber unter Linux/Unix möglich mehr zu machen: Das Modul popen2 stell dieselben Funktionen bereit (Rückgabewerte in anderer Reihenfolge), aber es sind unter Linux auch noch die KLassen Popen3 und Popen4 verfügbar. Von denen kann man ableiten und damit eventuell was anstellen.

hth, Milan
Benutzeravatar
NEBULA
User
Beiträge: 25
Registriert: Mittwoch 5. März 2003, 11:59
Wohnort: Kleve/NRW

Beitragvon NEBULA » Montag 29. März 2004, 16:06

Ich hatte hier bei mir ein aehnliches Problem:

Ich habe unter Linux den mplayer im Slave-Modus gestartet und wollte natuerlich auch die Antworten lesen die bei einem get_percent_length kommen :) und das funktionierte auch am Anfang so irgendwie gar nicht.
Erst bei Beendigung des Programmes, konnte mein Popen3-Objekt vom stdout-Dateiobjekt lesen....

Mir ist eingefallen, dass die Jungs von Freevo wohl auch vor diesem Problem gestanden haben muessen und richtig.

Tip daher:

Freevo-Quellcode herunterladen und dort nach childapp.py suchen ;)
Ich bin hingegangen und habe versucht von Grund auf dieses Modul nachzubilden, es funktioniert aber leider......

So richtig durchgeblickt habe ich da ehrlich gesagt nicht, aber der Trick besteht wohl darin in einem eigenen Thread an den Ausgabestreams(stdout und stderr) zu lauschen.
Meine "mplayer Aufgabe" funktioniert nun auch so wie man sich das wuenscht.

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot]