subprocess Ausgaben in "Echtzeit" verarbeiten
Ich hab ein Problem mit subprocess. Ich versuche die Ausgaben eines Programms in Echtzeit zu verarbeiten. Das funktioniert aber nur bei Programmen die ein stdout.flush() machen. Macht das ein Programm nicht, dann bekommt man erst die Ausgaben, wenn das Programm beendet ist. Das eigentliche Problem wird ganz gut hier erklärt: http://www.noah.org/wiki/Pexpect#Q:_Why_not_just_use_a_pipe_.28popen.28.29.2... Demnach ist es so, das viele Programme zur Ausgabe die Standard C IO Library (stdio.h) nutzten. stdio.h bekommt mit, ob "am Ende" ein Terminal oder eine PIPE ist. Bei eine Ausgabe in eine PIPE puffert stdio.h von sich aus die Daten. Pexpect umgeht das ganze anscheinend in dem es dem das Programm ein Pseudo-Terminal vorsetzt wird. Doch das funktioniert unter Windows nicht wirklich, siehe: http://www.noah.org/wiki/Pexpect#pty_module Wie kann man das ganze unter Windows in den Griff bekommen??? (Das selbe gibt's auch im Forum: http://www.python-forum.de/topic-16459.html ) -- Mfg. Jens Diemer ---- http://www.jensdiemer.de
Wie kann man das ganze unter Windows in den Griff bekommen???
Wenn Du die Quellen des Programms has, kannst Du es derart neu übersetzen, dass es für stdout die Pufferung immer ausschaltet (mittels setvbuf); ein fflush ist dann nicht nötig. Wenn Du die Quellen nicht hast, kannst Du gar nichts machen. Ciao, Martin
Aber dann verstehe ich etwas grundsätzlich nicht. Wenn das Programm in der Eingabeaufforderung gestartet wurde, sehe ich doch auch die Ausgabe direkt und nicht erst dann, wenn der Puffer voll ist, oder ein flush gemacht wurde. Ich kann das Verhalten also nicht mit Python "nachbauen"? Martin v. Löwis schrieb:
Wie kann man das ganze unter Windows in den Griff bekommen???
Wenn Du die Quellen des Programms has, kannst Du es derart neu übersetzen, dass es für stdout die Pufferung immer ausschaltet (mittels setvbuf); ein fflush ist dann nicht nötig.
Wenn Du die Quellen nicht hast, kannst Du gar nichts machen.
Ciao, Martin
_______________________________________________ python-de maillist - python-de@python.net http://python.net/mailman/listinfo/python-de
-- Mfg. Jens Diemer ---- http://www.jensdiemer.de
Am Dienstag 11 November 2008 14:37:34 schrieb Jens Diemer:
Aber dann verstehe ich etwas grundsätzlich nicht. Wenn das Programm in der Eingabeaufforderung gestartet wurde, sehe ich doch auch die Ausgabe direkt und nicht erst dann, wenn der Puffer voll ist, oder ein flush gemacht wurde.
Wieso verstehst du das nicht? Du hast doch in deinem Eingangsposting bereits festgestellt, dass die libc zwischen TTYs und Pipes unterscheidet. Du kannst aber das Verhalten des aufgerufenen Programms nicht beeinflussen, es sei denn, du änderst die Quellen der libc oder des Programms und übersetzt diese neu. Du kannst die libc höchstens überlisten, in dem du ein Terminal emulierst. Unter Linux/Unix ist pexpect das Mittel der Wahl, unter Windows wohl pywin32 und eine Recherche in den Untiefen der MSDN. -- Freiheit ist immer die Freiheit der Andersdenkenden. (Rosa Luxemburg)
Du hast recht, im Grunde war mir es klar. Ich muß wohl meine Frage umstellen ;) "Wie kann man ein Terminal unter Windows emulieren?" Sebastian Wiesner schrieb:
Du kannst die libc höchstens überlisten, in dem du ein Terminal emulierst. Unter Linux/Unix ist pexpect das Mittel der Wahl, unter Windows wohl pywin32 und eine Recherche in den Untiefen der MSDN.
Das ist schonmal eine grobe Richtung. Ich kann mir allerdings nicht vorstellen, das ich der erste Python Programmierer bin, der sowas machen möchte. Kennt jemand also ein Beispiel? -- Mfg. Jens Diemer ---- http://www.jensdiemer.de
Aber dann verstehe ich etwas grundsätzlich nicht. Wenn das Programm in der Eingabeaufforderung gestartet wurde, sehe ich doch auch die Ausgabe direkt und nicht erst dann, wenn der Puffer voll ist, oder ein flush gemacht wurde.
Wie Sebastian erklärt: das Programm ruft isatty - das ist (letztlich) ein Systemruf, der bei einem Terminal "ja" und bei einer Pipe "nein" sagt.
Ich kann das Verhalten also nicht mit Python "nachbauen"?
Du kannst das Verhalten nicht mit dem Windows API nachbauen - auch nicht, wenn das andere Ende der Pipe in C oder Assembler geschrieben wäre. Du müsstest schon Windows selbst ändern (konkret: GetFileType) cygwin emuliert pseudo-terminals irgendwie mit named-pipes. Dazu werden ein paar Hilfsthreads gestartet, SetNamedPipeHandleState aufgerufen usw. - mir ist allerdings nicht klar, was sie damit letztlich erreichen (wohl im Wesentlichen, dass mehrere Prozesse gleichzeitig /dev/pty/foo öffnen können). Ob das bei der Puffering von msvcrt hilft, weiß ich nicht - wohl eher nur bei der Pufferung in cygwin-Prozessen. Ciao, Martin
participants (3)
-
"Martin v. Löwis"
-
Jens Diemer
-
Sebastian Wiesner