¿Cómo limitar el número de líneas que la salida de un comando tiene disponible en bash?

11

Empecé a descargar un archivo grande en segundo plano usando

$ nohup wget http://example.tld/big.iso &

que también me da un nohup.outarchivo que incluye la salida de wget.

Ahora, si luego quiero ver el proceso de descarga, podría usarlo, $ tail -f nohup.outpero eso llena la ventana de mi terminal más rápido de lo que desearía. Lo que me gustaría ver es la última línea que se actualiza constantemente (al igual que cuando se usa wgetsolo).

Lo intenté $ tail -n 1 -f nohup.outpero parece afectar solo la cola inicial.

En términos generales, si es posible limitar (en este caso a 1) el número de líneas que la salida de un comando tiene disponible / visible, resolvería este problema. Es como tener la salida en un búfer circular : solo piense en la barra de progreso normal que $ wget example.tld/big.isose imprimiría.

¿Existe tal solución?

¿O estoy subiendo al árbol de manera incorrecta? (Es decir, ¿sería más fácil limitar nohupla salida o hacer otra cosa?)

Jari Keinänen
fuente

Respuestas:

10

Si no desea limitar la región de desplazamiento (consulte mi otra respuesta), también puede usar el retorno de carro para volver al principio de la línea antes de imprimir la siguiente línea. Hay una secuencia de escape que borra el resto de la línea, que es necesaria cuando la línea actual es más corta que la línea anterior.

nohup wget http://cdimage.debian.org/debian-cd/6.0.3/amd64/iso-dvd/debian-6.0.3-amd64-DVD-1.iso &
el="$(tput el)"; # Clear to the end of the line
tail -n 1 -f nohup.out | while read -r line; do echo -n $'\r'"$el$line"; done;
janmoesen
fuente
6

Puedes usar watchaquí:

watch -n 0.5 -e "tail -n 1 nohup.out"

Editar : la opción -e(alias --exec) parece adecuada aquí. Especialmente si apunta a correr watchcon intervalos muy pequeños, esto reduce la sobrecarga causada por correr sh -cinternamente watchen cada ciclo.

rozcietrzewiacz
fuente
2
Tenga en cuenta que esto genera un nuevo tailproceso cada segundo, que podría o no ser algo que le interese. Además, asegúrese de especificar un intervalo de sub-segundo (por ejemplo watch -n 0.1) para simular la parte de "actualización constante". (Obviamente, esto también aumenta la cantidad de procesos y llamadas abiertas de archivo). Finalmente, si está utilizando OS X, puede obtenerlo watchde MacPorts, ya que no está disponible de forma predeterminada.
Janmoesen
Esto es un poco alternativo, pero genial como tal. Esperaba una respuesta que no fuera de pantalla completa, para poder ver salidas anteriores, pero realmente podría usar watchen una nueva ventana de terminal. También descubrí que usar tail -n 2es más útil que -n 1con wget, al menos con un watchintervalo de 1 segundo, porque de lo contrario el último porcentaje podría no verse; Esto no es un defecto en su respuesta, pero lo mencioné si alguien más decide ver la salida de cola de wgets.
Jari Keinänen
@janmoesen Para este escenario específico, tener un nuevo tailproceso probablemente no sea demasiado exagerado; pero como respuesta general, es bueno tenerlo en cuenta. También noté que watch -n 0.1no funcionó, pero watch -n 0,1funcionó: podría haber configuraciones regionales aplicadas, aunque no he visto configuraciones regionales aplicadas a las opciones de comando de terminal antes. Como nota al margen: también brew install watchfuncionó muy bien :-)
Jari Keinänen
Una nota al margen: si watchfuncionará con su configuración regional 0,1o 0.1depende de ella (utiliza el símbolo decimal definido para su configuración regional). Compruebe LC_ALL=C watch -n 0.1 "date +%S.%N".
rozcietrzewiacz
3

Hay ciertas secuencias de control de Xterm que puede usar para limitar las líneas de su terminal que se desplazan. Busque "Establecer región de desplazamiento". Sin embargo, es un poco un error. Asegúrese de reiniciar su terminal después:

nohup wget http://cdimage.debian.org/debian-cd/6.0.3/amd64/iso-dvd/debian-6.0.3-amd64-DVD-1.iso &
clear; echo -n $'\e[1;2r'; tail -f nohup.out | grep --line-buffered .
# The "grep" line is to ensure a single line; you can also use "awk 1" or "sed" etc.
janmoesen
fuente
<Inserte la nota habitual sobre la no portabilidad aquí>
Janmoesen
Esta es otra gran alternativa, pero también se usa mejor en una ventana dedicada, ya que tail -ftodavía llena el búfer y también porque el terminal necesita reiniciarse después de todos modos. Esto no está tan en línea como esperaba, pero de lo contrario podría ser lo que buscaba.
Jari Keinänen
0

Si no desea que la salida ocupe toda la ventana de terminal actual, puede usar un whilebucle simple :

while true; do 
  XXX=$( tail -n1 my.log )
  echo -en " \r$XXX\r"
  sleep 0.5
done; echo
rozcietrzewiacz
fuente
1
Tenga en cuenta que para poder desplazar la salida del terminal mientras se ejecuta cualquier comando de producción de salida, debe editar la configuración del emulador de terminal y deshabilitar scrollTtyOutput(o una opción similar).
rozcietrzewiacz