Línea de fuerza-buffering de stdout cuando tubería a tee
Normalmente, stdout
es un búfer de línea. En otras palabras, siempre y cuando 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 programa C++, a
, que produce cadenas, siempre \n
terminadas, a stdout
.
Cuando se ejecuta por sí mismo (./a
), todo se imprime correctamente y en el momento adecuado, como se esperaba. Sin embargo, si lo canalizo tee
(./a | tee output.txt
), no imprime cualquier cosa hasta que se detenga, lo que frustra el propósito de usar tee
.
Sé que podría arreglarlo agregando un fflush(stdout)
después de cada operación de impresión en el programa 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 tener un búfer de línea, incluso cuando use una tubería?
5 answers
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-05 02:50:35
Puedes probar stdbuf
$ stdbuf -o 0 ./a | tee output.txt
(grande) parte de la página de manual:
-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.
Tenga esto en cuenta, sin embargo:
NOTE: If COMMAND adjusts the buffering of its standard streams ('tee' does
for e.g.) 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ás ejecutando stdbuf
en tee
, lo estás ejecutando en a
, por lo que esto no debería afectarte, a menos que establezcas el búfer de los flujos de a
en la fuente de a
.
También, stdbuf
es no POSIX, sino parte de GNU-coreutils.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-05 02:10:44
También puede intentar ejecutar su comando en un pseudo-terminal usando el comando script
(que debería imponer la salida de búfer de línea a la tubería)!
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 script
no propaga el estado de salida del comando envuelto.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-19 05:45:26
Puede usar setlinebuf desde stdio.h.
setlinebuf(stdout);
Esto debería cambiar el buffering a "line buffered".
Si necesita más flexibilidad puede usar setvbuf.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-14 14:46:50
Si utiliza las clases de flujo de C++ en su lugar, cada std::endl
es un color implícito. Usando la impresión de estilo C, creo que el método que sugirió (fflush()
) es la única manera.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-05 03:12:29