Zwykle stdout
jest buforowany wierszami. Innymi słowy, dopóki printf
argument kończy się znakiem nowej linii, możesz oczekiwać, że zostanie on natychmiast wydrukowany. Wydaje się, że nie działa, gdy używasz potoku do przekierowania tee
.
Mam program w C ++ a
, który wyprowadza ciągi, zawsze \n
zakończone, do stdout
.
Gdy jest uruchamiany samodzielnie ( ./a
), wszystko jest drukowane poprawnie i we właściwym czasie, zgodnie z oczekiwaniami. Jeśli jednak prześlę to do tee
( ./a | tee output.txt
), nic nie drukuje, dopóki nie zakończy pracy, co jest sprzeczne z celem użycia tee
.
Wiem, że mogłem to naprawić dodając fflush(stdout)
po każdej operacji drukowania w programie C ++. Ale czy istnieje czystszy i łatwiejszy sposób? Czy istnieje polecenie, które mogę uruchomić, na przykład, które stdout
wymusiłoby buforowanie liniowe, nawet przy użyciu potoku?
expect
ponieważunbuffer
nie wydaje się być domyślnie uwzględniony w systemie OS X.unbuffer
to tylko mały skrypt, więc nie powinieneś był potrzebować rekompilować całego pakietu../configure && make
zajęło to około 10 sekund, a potem po prostu przeniosłem sięunbuffer
do/usr/local/bin
:)unbuffer {commands with pipes/tee}
.możesz spróbować
stdbuf
(duża) część strony podręcznika:
pamiętaj jednak o tym:
nie biegasz
stdbuf
dalejtee
, ty go uruchamiasza
, więc nie powinno to mieć na ciebie wpływu, chyba że ustawisz buforowaniea
strumieni wa
źródle.Ponadto nie
stdbuf
jest POSIX, ale częścią GNU-coreutils.źródło
stdbuf
jest już dostępna w dystrybucjach Centos Linux, których używamy, iunbuffer
nie jest. Dzięki!-u
do wyłączenia buforowania po stronie Pythona:python3 -u a.py | tee output.txt
Możesz także spróbować wykonać swoje polecenie w pseudoterminalu, używając
script
polecenia (co powinno wymusić buforowanie linii na potoku)!Należy pamiętać, że
script
polecenie nie propaguje z powrotem statusu zakończenia opakowanej komendy.źródło
script -t 1 /path/to/outputfile.txt ./a
działał świetnie w moim przypadku użycia. Na żywo przesyła wszystkie dane wyjściowe do,outputfile.txt
jednocześnie drukując je na standardowe wyjście powłoki. Nie trzeba było używaćtee
Możesz użyć setlinebuf z stdio.h.
Powinno to zmienić buforowanie na „buforowane liniowo”.
Jeśli potrzebujesz większej elastyczności, możesz użyć setvbuf.
źródło
setvbuf(stdout, NULL, _IOLBF, 0)
, co jest dokładnie równoważne.Jeśli zamiast tego używasz klas strumienia C ++, każdy
std::endl
jest niejawnym opróżnieniem. Używając drukowania w stylu C, myślę, że metoda, którą zasugerowałeś (fflush()
), jest jedynym sposobem.źródło
#include <iostream> #include <unistd.h> int main(void) { std::cout << "1" << std::endl; sleep(1); std::cout << "2" << std::endl; }
. endl zawsze opróżniaunbuffer
Komenda zexpect
pakietu na @Paused aż do wypowiedzenia dalszego odpowiedź nie pracował dla mnie sposób, w jaki został przedstawiony.Zamiast używać:
./a | unbuffer -p tee output.txt
Musiałem użyć:
unbuffer -p ./a | tee output.txt
expect
Pakiet można zainstalować na:pacman -S expected
brew install expected
źródło