Por lo general, stdouttiene búfer de línea. En otras palabras, siempre que su printfargumento 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 \nterminadas, 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 stdouta tener búfer de línea, incluso cuando se usa una tubería?

expectyaunbufferque no parece estar incluido de forma predeterminada en OS X.unbufferes solo un pequeño script, por lo que no debería haber tenido que volver a compilar todo el paquete../configure && maketomó unos 10 segundos y luego me mudéunbuffera/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
stdbufentee, 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
stdbufes POSIX, sino parte de GNU-coreutils.fuente
stdbufya está disponible en las distribuciones de Centos Linux que estamos usando, yunbufferno lo está. ¡Gracias!-upara 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
scriptcomando (que debería hacer cumplir la salida con búfer de línea en la tubería)!Tenga en cuenta que el
scriptcomando no propaga el estado de salida del comando empaquetado.fuente
script -t 1 /path/to/outputfile.txt ./afuncionó muy bien para mi caso de uso. Transmite en vivo toda la salida al mismooutputfile.txttiempo que la imprime en la salida estándar de su shell. No necesitaba usarteePuede 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::endles 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