Normalerweise stdout
ist zeilengepuffert. Mit anderen Worten, solange Ihr printf
Argument mit einer neuen Zeile endet, können Sie erwarten, dass die Zeile sofort gedruckt wird. Dies scheint nicht zu gelten, wenn Sie eine Pipe zum Umleiten verwenden tee
.
Ich habe ein C ++ - Programm, a
das Zeichenfolgen ausgibt, die immer abgeschlossen \n
sind stdout
.
Wenn es von selbst ausgeführt wird ( ./a
), wird alles wie erwartet korrekt und zur richtigen Zeit gedruckt. Wenn ich es jedoch an tee
( ./a | tee output.txt
) weitergebe, wird nichts gedruckt, bis es beendet wird, was den Verwendungszweck zunichte macht tee
.
Ich weiß, dass ich das Problem beheben kann, indem ich fflush(stdout)
nach jedem Druckvorgang im C ++ - Programm ein hinzufüge . Aber gibt es einen saubereren und einfacheren Weg? Gibt es einen Befehl, den ich zum Beispiel ausführen kann, der die Zeilenpufferung erzwingen würde stdout
, selbst wenn eine Pipe verwendet wird?
expect
mich selbst kompilieren musste, daunbuffer
es in OS X nicht standardmäßig enthalten zu sein scheint.unbuffer
ist nur ein kleines Skript, daher hätten Sie das gesamte Paket nicht neu kompilieren müssen../configure && make
dauerte ungefähr 10 Sekunden und dann bin ich einfachunbuffer
zu/usr/local/bin
:)unbuffer {commands with pipes/tee}
.Du kannst es versuchen
stdbuf
(großer) Teil der Manpage:
Beachten Sie jedoch Folgendes:
Sie laufen nicht
stdbuf
weitertee
, Sie laufen weitera
, daher sollte dies Sie nicht betreffen, es sei denn, Sie legen die Pufferung dera
Streams ina
der Quelle fest.Auch
stdbuf
ist nicht POSIX, sondern Teil von GNU-Coreutils.quelle
stdbuf
bereits in den von uns verwendeten Centos Linux-Distributionen verfügbar ist undunbuffer
nicht. Vielen Dank!-u
Pufferung auf Pythons Seite deaktivieren:python3 -u a.py | tee output.txt
Sie können auch versuchen, Ihren Befehl in einem Pseudo-Terminal mit dem
script
Befehl auszuführen (der die zeilengepufferte Ausgabe an die Pipe erzwingen soll)!Beachten Sie, dass der
script
Befehl den Exit-Status des umschlossenen Befehls nicht zurückgibt.quelle
script -t 1 /path/to/outputfile.txt ./a
funktionierte hervorragend für meinen Anwendungsfall. Es überträgt alle Ausgaben live anoutputfile.txt
und druckt sie gleichzeitig auf die Standardausgabe Ihrer Shell. Musste nicht verwendentee
Sie können setlinebuf von stdio.h verwenden.
Dies sollte die Pufferung in "zeilengepuffert" ändern.
Wenn Sie mehr Flexibilität benötigen, können Sie setvbuf verwenden.
quelle
setvbuf(stdout, NULL, _IOLBF, 0)
, was genau gleichwertig ist.Wenn Sie stattdessen die C ++ - Stream-Klassen verwenden, handelt es sich bei jedem
std::endl
um einen impliziten Flush. Ich denke, beim Drucken im C-Stil ist die von Ihnen vorgeschlagene Methode (fflush()
) der einzige Weg.quelle
#include <iostream> #include <unistd.h> int main(void) { std::cout << "1" << std::endl; sleep(1); std::cout << "2" << std::endl; }
. endl leert