bash: force exec''d process para tener stdout sin búfer
logging unbuffered-output (6)
Algunos programas de línea de comando tienen una opción para modificar su comportamiento de almacenamiento en búfer de corriente stdout. Así que ese es el camino a seguir si la fuente C está disponible ...
# two command options ...
man file | less -p ''--no-buffer''
man grep | less -p ''--line-buffered''
# ... and their respective source code
# from: http://www.opensource.apple.com/source/file/file-6.2.1/file/src/file.c
if(nobuffer)
(void) fflush(stdout);
# from: http://www.opensource.apple.com/source/grep/grep-28/grep/src/grep.c
if (line_buffered)
fflush (stdout);
Como alternativa al uso del guión de desempate de expect o la modificación del código fuente del programa, también puede intentar usar el guión (1) para evitar contratiempos causados por un conducto:
Ver: engañar a una aplicación para que piense que su stdin es interactiva, no una pipa
# Linux
script -c "[executable string]" /dev/null
# FreeBSD, Mac OS X
script -q /dev/null "[executable string]"
Tengo un script como:
#!/bin/bash
exec /usr/bin/some_binary > /tmp/my.log 2>&1
El problema es que some_binary
envía todo su registro a stdout, y el almacenamiento en búfer lo hace de modo que solo vea la salida en fragmentos de unas pocas líneas. Esto es molesto cuando algo se atasca y necesito ver lo que dice la última línea.
¿Hay alguna manera de hacer stdout sin búfer antes de hacer el ejecutivo que afectará a algunos_binary por lo que tiene un registro más útil?
(El script de envoltura solo establece algunas variables de entorno antes del ejecutor, por lo que una solución en Perl o Python también sería factible).
Busqué en los internets una respuesta, y nada de esto funcionó para uniq
que es demasiado terco para almacenar todo excepto por stdbuf
:
{piped_command_here} | stdbuf -oL uniq | {more_piped_command_here}
GNU Coreutils-8 incluye un programa llamado stdbuf que esencialmente hace el truco LD_PRELOAD. Funciona en Linux y, según los informes, funciona en sistemas BSD.
GNU coreutils-8.5 también tiene el comando stdbuf
para modificar el almacenamiento en búfer de la secuencia de E / S.
http://www.pixelbeat.org/programming/stdio_buffering/
Entonces, en su caso de ejemplo, simplemente invoque:
exec stdbuf -oL /usr/bin/some_binary > /tmp/my.log 2>&1
Esto permitirá que el texto aparezca inmediatamente línea por línea (una vez que se completa una línea con el carácter "/n"
al final de la línea en C). Si realmente quiere salida inmediata, use -o0
en -o0
lugar.
De esta manera podría ser más deseable si no desea introducir la dependencia para expect
través del comando de un unbuffer
. Por otro lado, se necesita la forma de some_binary
, si es necesario engañar a some_binary
para que piensen que se enfrenta a una salida estándar real.
Puede encontrar que la secuencia de comandos de un unbuffer
que viene con expect
puede ayudar.
Una variable de entorno puede configurar el modo de IO del terminal como no búfer.
exportar NSUnbufferedIO = SÍ
Esto configurará el terminal sin búfer para los comandos de salida del terminal C y Ojective-C.