Come limitare il numero di righe disponibili nell'output di un comando in bash?


11

Ho iniziato a scaricare un file di grandi dimensioni in background utilizzando

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

che mi dà anche un nohup.outfile che include l'output di wget.

Ora, se in seguito volessi vedere il processo di download, potrei usarlo $ tail -f nohup.outma questo riempie la finestra del mio terminale più velocemente di quanto vorrei. Quello che mi piacerebbe vedere è l'ultima riga in costante aggiornamento (proprio come quando si usa wgetda solo).

Ci ho provato $ tail -n 1 -f nohup.outma sembra influenzare solo la coda iniziale.

In generale, se è possibile limitare (in questo caso a 1) il numero di righe disponibili / visibili dell'output di un comando, questo risolverebbe questo problema. Una specie di avere l'output in un buffer circolare : basti pensare alla normale barra di avanzamento che $ wget example.tld/big.isoverrebbe stampata.

Esiste una soluzione del genere?

O sto scalando l'albero nel modo sbagliato? (Significato, sarebbe più semplice limitare nohupl'output o fare qualcos'altro?)

Risposte:


10

Se non si desidera limitare la regione di scorrimento (vedere la mia altra risposta), è anche possibile utilizzare il ritorno a capo per tornare all'inizio della riga prima di stampare la riga successiva. Esiste una sequenza di escape che cancella il resto della linea, che è necessario quando la linea corrente è più corta della linea precedente.

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;

6

Puoi usare watchqui:

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

Modifica : l' opzione -e(alias --exec) sembra adatta qui. Soprattutto se si mira a correre watchcon intervalli molto piccoli, questo riduce il sovraccarico causato dalla corsa sh -cinterna watchin ogni ciclo.


2
Nota che questo genera un nuovo tailprocesso ogni secondo, che potrebbe essere o non essere qualcosa che ti interessa. Inoltre, assicurarsi di specificare un intervallo di un secondo (ad es. watch -n 0.1) Per simulare la parte "in costante aggiornamento". (Ciò ovviamente aumenta il numero di processi e anche le chiamate aperte di file.) Infine, se si utilizza OS X, è possibile ottenere watchda MacPorts, poiché non è disponibile per impostazione predefinita.
Janmoesen,

Questo è un po 'workaroundish, ma ottimo come tale. Mi aspettavo una risposta non a schermo intero, in modo da poter vedere gli output precedenti, ma in realtà avrei potuto utilizzarlo watchin una nuova finestra del terminale. Ho anche scoperto che l'utilizzo tail -n 2è più utile che -n 1con wget, almeno con un watchintervallo di 1 secondo, perché altrimenti la percentuale più recente potrebbe non essere vista; questo non è un difetto nella tua risposta, ma l'ho menzionato se qualcun altro decide di guardare l'output nohup della coda.
Jari Keinänen,

@janmoesen Per questo scenario specifico, tailprobabilmente avere un nuovo processo non è eccessivo; ma come risposta generale è bene tenerne conto. Ho anche notato che watch -n 0.1non ha funzionato, ma ha watch -n 0,1funzionato: potrebbero esserci delle localizzazioni applicate, anche se non ho mai visto delle localizzazioni applicate alle opzioni di comando del terminale. Come nota a margine: ha brew install watchfunzionato alla grande anche :-)
Jari Keinänen,

Una nota a margine: se watchfunzionerà con 0,1o 0.1dipende dalle impostazioni della propria locale (utilizza il simbolo decimale definito per la propria locale). Controllare LC_ALL=C watch -n 0.1 "date +%S.%N".
rozcietrzewiacz,

3

Esistono alcune sequenze di controllo Xterm che puoi usare per limitare le linee del tuo terminale che sono state fatte scorrere. Cerca "Imposta regione di scorrimento". Tuttavia, è un po 'difficile. Assicurati di ripristinare il terminale in seguito:

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.

<Inserisci qui la solita nota sulla non portabilità>
janmoesen,

Questa è un'altra ottima alternativa, ma che è anche meglio utilizzata nella finestra dedicata poiché tail -friempie ancora il buffer e anche perché il terminale deve comunque essere ripristinato in seguito. Questo non è così in linea come speravo, ma altrimenti potrebbe essere quello che ho cercato.
Jari Keinänen,

0

Se non si desidera che l'output occupi l'intera finestra del terminale corrente, è possibile utilizzare un semplice whileciclo:

while true; do 
  XXX=$( tail -n1 my.log )
  echo -en " \r$XXX\r"
  sleep 0.5
done; echo

1
Si noti che per poter scorrere l'output del terminale mentre è in esecuzione qualsiasi comando di produzione dell'output, è necessario modificare le impostazioni dell'emulatore di terminale e disabilitare l' scrollTtyOutputopzione (o simile).
rozcietrzewiacz,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.