Escribí un programa (en Ruby) y funcionó bien. Imprime algunas líneas de texto, luego hace una pausa por un minuto y luego repite lo anterior.
Funciona bien (en la terminal de Mac OS X), pero noté que si quería mantener un registro de la salida, usando
ruby myscript.rb | tee record.txt
entonces el resultado no se mostrará en la pantalla hasta que alcance una cierta cantidad, tal vez unos pocos kb. Sin embargo, esto podría significar 5 o 10 minutos sin nada en la pantalla (y tampoco nada en el archivo si presiono CTRL-C).
Podría modificar el programa para vaciar la salida, pero pensé que una aplicación debería ser independiente de lo que se utiliza con la salida a STDOUT. Entonces, ¿se puede tee
hacer que funcione bien (tal vez con una opción), o se podría usar cualquier otro comando, o tal vez sea una opción de Bash o la aplicación Terminal? ¿Hay alguna manera?
Respuesta1
Pensé que una aplicación debería ser independiente de lo que se utiliza con la salida a STDOUT.
Pensaste mal. Las bibliotecas de tiempo de ejecución de varios lenguajes de programación, incluidos los lenguajes C y C++, comparten la semántica de cambiar el almacenamiento en búfer según detectan que la secuencia está conectada a un dispositivo terminal.
Esta es una parte definida del lenguaje en muchos casos. El estándar del lenguaje C dice, por ejemplo:
Tal como se abrió inicialmente, el flujo de error estándar no está completamente almacenado en el búfer; los flujos de entrada estándar y de salida estándar se almacenan completamente en el buffer si y solo si se puede determinar que el flujo no hace referencia a un dispositivo interactivo.
La opción habitual si una secuencia no está conectada a un dispositivo terminal es seleccionar almacenamiento en búfer unitario, almacenamiento en búfer de línea o almacenamiento en búfer completo. El almacenamiento en búfer de unidades y el almacenamiento en búfer de líneas son habituales para el error estándar; almacenamiento en búfer completo para salida estándar. Pero esto varía según el idioma.
Entonces, para que la salida no esté completamente almacenada en el búfer cuando el flujo de salida es una tubería en dichos lenguajes, debe
- escriba su programa por sí mismo y haga que la línea de salida estándar esté almacenada en búfer, con búfer inteligente o sin búfer;
- use cosas que conecten la biblioteca de tiempo de ejecución de su lenguaje de programación particular, como el
stdbuf
comandosisu lenguaje de programación es C o utiliza (la parte de los flujos de E/S) la biblioteca de tiempo de ejecución de C como base (algo que algunos lenguajes de programación no hacen); o - use herramientas como
ptybandage
esas que hacen que el programa piense que su salida estándar es una terminal, mientras toma esa salida y la envía al extremo de escritura de la tubería.
Otras lecturas
Respuesta2
Por favor mira la respuestahttps://stackoverflow.com/a/11337109/5656721ya que es un problema común. Podrías usarstdbuffoquitar el búferpara su programa Ruby también.