Por lo general, stdout
tiene búfer de línea. En otras palabras, siempre que su printf
argumento 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 redireccionar tee
.
Tengo un programa C ++ a
, que genera cadenas, siempre \n
terminadas, a stdout
.
Cuando se ejecuta solo ( ./a
), todo se imprime correctamente y en el momento adecuado, como se esperaba. Sin embargo, si lo canalizo a tee
( ./a | tee output.txt
), no imprime nada hasta que se cierra, lo que anula 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 programa C ++. Pero, ¿existe una forma más limpia y sencilla? ¿Hay algún comando que pueda ejecutar, por ejemplo, que obligaría stdout
a tener búfer de línea, incluso cuando se usa una tubería?
expect
yaunbuffer
que no parece estar incluido de forma predeterminada en OS X.unbuffer
es solo un pequeño script, por lo que no debería haber tenido que volver a compilar todo el paquete../configure && make
tomó unos 10 segundos y luego me mudéunbuffer
a/usr/local/bin
:)unbuffer {commands with pipes/tee}
.puedes probar
stdbuf
(gran) parte de la página de manual:
Sin embargo, tenga esto en cuenta:
no se está ejecutando
stdbuf
entee
, que se está ejecutando ena
, por lo que esto no debe afectar, a menos que establezca el búfer dea
's corrientes ena
' fuente s.Además, no
stdbuf
es POSIX, sino parte de GNU-coreutils.fuente
stdbuf
ya está disponible en las distribuciones de Centos Linux que estamos usando, yunbuffer
no lo está. ¡Gracias!-u
para deshabilitar el almacenamiento en búfer en el lado de Python:python3 -u a.py | tee output.txt
¡También puede intentar ejecutar su comando en un pseudo-terminal usando el
script
comando (que debería hacer cumplir la salida con búfer de línea en la tubería)!Tenga en cuenta que el
script
comando no propaga el estado de salida del comando empaquetado.fuente
script -t 1 /path/to/outputfile.txt ./a
funcionó muy bien para mi caso de uso. Transmite en vivo toda la salida al mismooutputfile.txt
tiempo que la imprime en la salida estándar de su shell. No necesitaba usartee
Puede usar setlinebuf desde stdio.h.
Esto debería cambiar el almacenamiento en búfer a "búfer de línea".
Si necesita más flexibilidad, puede usar setvbuf.
fuente
setvbuf(stdout, NULL, _IOLBF, 0)
, que es exactamente equivalente.Si usa las clases de flujo de C ++ en su lugar, cada
std::endl
es un vaciado implícito. Usando la impresión de estilo C, creo que el método que sugirió (fflush()
) es la única forma.fuente
#include <iostream> #include <unistd.h> int main(void) { std::cout << "1" << std::endl; sleep(1); std::cout << "2" << std::endl; }
. endl siempre vacía el búfer como se define aquí: en.cppreference.com/w/cpp/io/manip/endl