Ich habe ein Python-Programm, das langsam eine Ausgabe generiert.
Ich möchte das in einer Datei festhalten, dachte aber auch, dass ich es mit Tail live ansehen könnte.
Also mache ich in einem Terminal:
python myprog.py > output.txt
und in einem anderen Terminal:
tail -f output.txt
Aber es scheint, als würde mir das Tail nichts anzeigen, während das Python-Programm läuft.
Wenn ich Strg+C drücke, um das Python-Skript zu beenden, output.txt
füllt sich das Ende plötzlich. Aber nicht, während Python ausgeführt wird.
Was mache ich falsch?
Antwort1
Möglicherweise müssen Sie den Puffer auch explizit leeren, damit er bei der Generierung weitergeleitet wird. Dies liegt daran, dass die Ausgabe normalerweise nur gedruckt wird, wenn der Puffer der Pipe voll ist (was, glaube ich, in Kilobyte ist) und wenn die Standardeingabenachricht endet. Dies dient wahrscheinlich dazu, Lese-/Schreibvorgänge zu sparen. Sie können dies nach jedem Ausdruck tun oder, wenn Sie eine Schleife ausführen, nach dem letzten Ausdruck innerhalb der Schleife.
import sys
...
print('Some message')
sys.stdout.flush()
Antwort2
Führen Sie Python mit dem ungepufferten Flag aus:
python -u myprog.py > output.txt
Die Ausgabe wird dann in Echtzeit gedruckt.
Antwort3
Anstatt zu versuchen, eine Live-Datei zu verfolgen, verwenden Sie tee
stattdessen. Es wurde entwickelt, um genau das zu tun, was Sie versuchen.
AusMann t:
tee(1) - Linux-Manpage
Name tee - von der Standardeingabe lesen und in die Standardausgabe und Dateien schreiben
Zusammenfassung
tee [OPTION]... [FILE]...
Beschreibung
Kopiert die Standardeingabe in jede DATEI und auch in die Standardausgabe.
-a, --append append to the given FILEs, do not overwrite -i, --ignore-interrupts ignore interrupt signals --help display this help and exit --version output version information and exit
Wenn eine DATEI - ist, erneut in die Standardausgabe kopieren.
In Ihrem Fall würden Sie also Folgendes ausführen:
python myprog.py | tee output.txt
BEARBEITEN: Wie andere bereits angemerkt haben, wird diese Antwort auf dasselbe Problem stoßen, das OP ursprünglich hatte, es sei denn, sys.stdout.flush()
es wird im Python-Programm verwendet, wie in Daveys akzeptierter Antwort beschrieben. Die Tests, die ich vor dem Posten dieser Antwort durchgeführt habe, spiegelten den Anwendungsfall von OP nicht genau wider.
tee
kann immer noch als alternative – wenn auch nicht optimale – Methode zum Anzeigen der Ausgabe bei gleichzeitigem Schreiben in die Datei verwendet werden, aber Daveys Antwort ist eindeutig die richtige und beste Antwort.
Antwort4
Wenn ich tail verwende, wird fast immer eine Protokolldatei verfolgt, z. B. (E-Mail-)Nachrichten.
Das klingt vielleicht etwas abwegig, aber warum verwenden Sie in Ihrem Python-Code nicht das Protokollierungsmodul, anstatt print
/ print()
/ write()
zu verwenden? (aus der PSL) NB: Ein Protokollierungsformatierer kann so konfiguriert werden, dass er NICHT alle Zeit- und ID-Codes ausgibt, die mit einem herkömmlichen Protokoll verknüpft sind.
Die Ausgabe kann so konfiguriert werden, dass sie in eine (Daten-)Datei erfolgt, und da es keine Pufferverzögerung oder Umleitung gibt, funktioniert tail problemlos und sofort.
Grüße