bash: force exec’d process para tener stdout sin búfer

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).

Puede encontrar que la secuencia de comandos de un unbuffer que viene con expect puede ayudar.

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.

Algunos progtwigs de línea de comando tienen una opción para modificar su comportamiento de almacenamiento en búfer de stream 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 progtwig, 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]" 

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 progtwig llamado stdbuf que esencialmente hace el truco LD_PRELOAD. Funciona en Linux y, según los informes, funciona en sistemas BSD.

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.