Forzar el almacenamiento en línea de la línea de salida estándar cuando se conectan al tee

Por lo general, stdout es buffer de línea. En otras palabras, siempre que su argumento printf termine con una nueva línea, puede esperar que la línea se imprima instantáneamente. Esto no parece mantenerse cuando se usa una tubería para redirigir a tee .

Tengo un progtwig en C ++, a , que envía cadenas, siempre \n -terminadas, a stdout .

Cuando se ejecuta solo ( ./a ), todo se imprime correctamente y en el momento correcto, como se esperaba. Sin embargo, si lo ./a | tee output.txt a tee ( ./a | tee output.txt ), no imprime nada hasta que se ./a | tee output.txt , lo que ./a | tee output.txt el propósito de usar tee .

Sé que podría solucionarlo agregando un fflush(stdout) después de cada operación de impresión en el progtwig C ++. Pero, ¿hay una manera más limpia y fácil? ¿Hay algún comando que pueda ejecutar, por ejemplo, que obligue a stdout a ser almacenado en línea, incluso cuando se usa una tubería?

Intenta unbuffer el unbuffer que es parte del paquete de expect . Es posible que ya lo tenga en su sistema.

puedes probar stdbuf

 $ stdbuf -o 0 ./a | tee output.txt 

(grande) parte de la página man:

  -i, --input=MODE adjust standard input stream buffering -o, --output=MODE adjust standard output stream buffering -e, --error=MODE adjust standard error stream buffering If MODE is 'L' the corresponding stream will be line buffered. This option is invalid with standard input. If MODE is '0' the corresponding stream will be unbuffered. Otherwise MODE is a number which may be followed by one of the following: KB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y. In this case the corresponding stream will be fully buffered with the buffer size set to MODE bytes. 

ten esto en cuenta, sin embargo:

 NOTE: If COMMAND adjusts the buffering of its standard streams ('tee' does for eg) then that will override corresponding settings changed by 'stdbuf'. Also some filters (like 'dd' and 'cat' etc.) dont use streams for I/O, and are thus unaffected by 'stdbuf' settings. 

no está ejecutando stdbuf en tee , lo está ejecutando en a , por lo que esto no debería afectarlo, a menos que configure el almacenamiento en búfer de las streams de a fuente.

Además, stdbuf no es POSIX, sino parte de GNU-coreutils.

También puede intentar ejecutar su comando en un pseudo-terminal utilizando el comando de script (que debería imponer la salida de buffer de línea al conducto).

 script -q /dev/null ./a | tee output.txt # Mac OS X, FreeBSD script -c "./a" /dev/null | tee output.txt # Linux 

Tenga en cuenta que el comando de script no propaga el estado de salida del comando envuelto.

Puede usar setlinebuf desde stdio.h.

 setlinebuf(stdout); 

Esto debería cambiar el almacenamiento en búfer a “línea almacenada en búfer”.

Si necesita más flexibilidad, puede usar setvbuf.

Si utiliza las clases de flujo C ++ en su lugar, cada std::endl es un color implícito. Al utilizar la impresión estilo C, creo que el método que sugirió ( fflush() ) es la única forma.