2011-05-08 8 views
5

Tengo un script que genera muchos resultados. El guión hace una pausa de unos segundos en el punto T.Tiempo tomado por el comando `less` para mostrar la salida

Ahora estoy usando el comando less para analizar el resultado del script. Entonces ejecuto ./script | less. Lo dejo funcionando por suficiente tiempo para que el script haya terminado de ejecutarse.

Ahora voy a la salida del comando menos presionando la tecla Pg Down. Sorprendentemente mientras se desplaza en el punto T de la salida, noto la pausa de unos segundos nuevamente.

El script no espera ninguna entrada y definitivamente se habrá completado para cuando empiece a analizar la salida de menos.

¿Alguien puede explicar cómo la pausa de unos segundos es notable en el resultado de menos cuando el script hubiera terminado de ejecutarse?

+0

Quizás esa página particular de la salida tenga una gran cantidad de texto, por ejemplo, si hay una línea horizontal extremadamente larga. – ninjagecko

Respuesta

8

Su secuencia de comandos se comunica con less a través de una tubería . Pipe es una secuencia de bytes en la memoria que conecta dos puntos finales: la secuencia de comandos y el programa less, la primera salida de escritura a la misma y la última lectura de la misma.

Como las tuberías están en la memoria, no sería agradable si crecieran arbitrariamente grandes. Por lo tanto, de forma predeterminada, hay un límite de datos que pueden estar dentro del conducto (escritos, pero aún no leídos) en cualquier momento dado. Por defecto es 64k en Linux. Si la tubería está llena y su secuencia de comandos intenta escribir en ella, escriba los bloques. Así que su script no está funcionando, se detuvo en algún momento al hacer una llamada write().

¿Cómo superar esto? Ajustar los valores predeterminados es una mala opción; lo que se usa en su lugar es asignar un búfer en el lector, de modo que se lea en el búfer, liberando la tubería y permitiendo así que el programa de escritura funcione, pero le muestra (o maneja) solo una parte de la salida. less tiene dicho búfer y, de forma predeterminada, lo expande automáticamente. Sin embargo, no lo llena en segundo plano, solo lo rellena a medida que lee la entrada.

Así lo resolvería su problema está leyendo el archivo hasta el final (como lo haría normalmente presione G), y luego ir de nuevo al principio (como lo haría normalmente presione g). La cosa es que usted puede especificar estos comandos a través de línea de comandos de la siguiente manera:

./script | less +Gg 

debe tener en cuenta, sin embargo, que va a tener que esperar hasta que las cargas de salida de toda la secuencia de comandos en la memoria, por lo que no podrán para verlo de una vez less no es lo suficientemente sofisticado para eso.Pero si eso es lo que realmente necesita (navegar por el inicio de la producción, mientras que el ./script todavía está calculando su fin), es posible que desee utilizar un archivo temporal:

./script >x & less x ; rm x 
+0

¿Qué ocurre si el script escribe en la salida estándar y segmenta en algún punto intermedio? La segfault puede evitar que la salida almacenada se escriba en el archivo x. Esto se debe a que la salida a un archivo está bloqueada de forma predeterminada y no está almacenada en la línea. ¿Puedo aplicar externamente el buffer de línea en el script? ¿Hay alguna utilidad de pseudo tty que pueda usar? –

2

La tubería está llena en el nivel del sistema operativo, por lo que script bloques hasta less consume parte de ella.

+0

Esto parece bastante fácil de probar, si solo obtiene su script para emitir cosas a un archivo de registro a medida que genera texto. – ninjagecko

2

Control de flujo. Su secuencia de comandos se está pausando de manera efectiva, mientras que menos es paginación.

Si desea asegurarse de que el comando se completa antes de utilizar menos de forma interactiva, invocar a menos que less +G y se leerá al final de la entrada, a continuación, puede volver al comienzo escribiendo en 1G menos.

0
Can I externally enforce line buffering on the script? 
Is there an off the shelf pseudo tty utility I could use? 

Usted puede tratar de utilizar el comando script para activar el modo de salida de línea-buffering.

script -q /dev/null ./script | less  # FreeBSD, Mac OS X 
script -c "./script" /dev/null | less # Linux 

Para más alternativas a este respecto, véase: Turn off buffering in pipe.

Cuestiones relacionadas