2010-08-12 7 views
42

¿Hay alguna forma de ejecutar comandos de shell sin almacenamiento en búfer de salida?¿Cómo hacer que la salida de cualquier comando de shell sea sin búfer?

Por ejemplo, hexdump file | ./my_script solo pasará la entrada de hexdump a my_script en fragmentos almacenados en búfer, no línea por línea.

En realidad, quiero saber una solución general sobre cómo hacer un comando sin búfer?

+1

más pregunta upvoted http://unix.stackexchange.com/questions/25372 –

Respuesta

9

AFAIK, no puedes hacerlo sin feos hacks. Escribir en un conducto (o leer de él) activa automáticamente el almacenamiento en búfer completo y no hay nada que pueda hacer al respecto :-(. "Buffer de línea" (que es lo que desea) solo se usa al leer/escribir un terminal. feos cortes es exactamente lo siguiente: se conectan un programa a una pseudo-terminal, de manera que las otras herramientas en el tubo de lectura/escritura de ese terminal en modo de línea de amortiguación todo el problema se describe aquí:.

La página también tiene algunas sugerencias (la ya mencionada "feos hacks") qué hacer, es decir, utilizando unbuffer o tirando algunos trucos con LD_PRELOAD.

+0

Gracias. Nunca había escuchado sobre pseudo terminales antes. – bodacydo

14

También puede utilizar el comando script para que la salida de hexdump línea de búfer (hexdump se ejecutará en un pseudo-terminal que engaña a hexdump para que piense que está escribiendo su estándar en un terminal, y no en un conducto).

# cf. http://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe/ 
stty -echo -onlcr 
script -q /dev/null hexdump file | ./my_script   # FreeBSD, Mac OS X 
script -q -c "hexdump file" /dev/null | ./my_script # Linux 
stty echo onlcr 
+0

Utilicé el parámetro -f para enjuagar, no estoy seguro si es necesario pero funcionó. –

+0

En mi caso, 'stdbuf' falló, pero el script funciona como un amuleto. El programa almacena la salida cuando se canaliza a 'tee', pero no cuando se ejecuta en la terminal. Entonces, ¡el script funciona! ¡Gracias! – TerrenceSun

+0

¡Solución muy inteligente, y funciona! Gracias. : smile: – xmnboy

85

Trate stdbuf, incluido en GNU coreutils y por lo tanto prácticamente cualquier distribución de Linux. Esto establece la longitud del búfer de entrada, salida y error a cero:

stdbuf -i0 -o0 -e0 command 
+6

Esto funcionó mejor que 'unbuffer' para mí. 'stdbuf' pasó cualquier señal (' SIGUSR2' en mi caso) Le envié al 'comando' (que es lo que quería que sucediera), mientras que' unbuffer' no parecía querer hacerlo. – ElDog

+0

respuesta más actualizada http://unix.stackexchange.com/a/25378/5510 –

+2

stdbuf usa uno de los trucos LD_PRELOAD antes mencionados para hacer esto y, por lo tanto, no funciona con ejecutables estáticamente vinculados o setuid. Vea esta pregunta para una discusión: http: // stackoverflow.com/questions/13644024/stdbuf-with-setuid-capabilities/18624182 # 18624182 –

Cuestiones relacionadas