Come visualizzare il numero di righe emesse da un comando in tempo reale?


15

Sto usando svn exportcome parte di uno script packager per la mia applicazione e sembra che questo comando, come molti altri, non abbia alcun tipo di barra di avanzamento.

Al momento ho due scelte:

  • usandolo senza opzioni e guardalo stampare migliaia di righe
  • usando --quiete non vedendo nulla fino al completamento.

C'è un modo per mostrare almeno il numero di righe emesse dal comando, in tempo reale? Ad esempio:

Exporting SVN directory ... 1234 files

E vedi questo 1234 incremento numerico in tempo reale ? Posso immaginare di inviare l'output a un comando che farebbe proprio questo, ma quale?

Risposte:


16
yourcommand | { I=0; while read; do printf "$((++I))\r"; done; echo ""; }

Oppure inserisci la sezione tra parentesi in uno script di shell. Nota che questo funziona solo se la tua shell in realtà supporta l'operatore di preincremento, come bash o ksh93 o zsh. Altrimenti dovrai incrementare $Ie quindi stamparlo (come in I=$((I+1));printf...). Inoltre, se printfnon è un builtin con la tua shell (è un builtin con bash corrente), puoi usare echo -neo print -ninvece per prestazioni migliori. Vuoi solo sopprimere la nuova riga e far interpretare il carattere di escape.


Oh, non mi farò mai imparare il bashscripting con tutte le sue brutte =e `=` differenze e stranezze. :) Perché non dovrebbero sostituirlo con un linguaggio sintattico simile al pitone ...
Boris Burkov,

Ehi, lo so, cosa! È possibile aggiungere il simbolo di ritorno a capo a ogni nuova riga stampata e non inonderà lo schermo, ma sovrascriverà solo la riga precedente.
Boris Burkov,

Ecco perché printffinisce con a \r. E cosa succede se lo fai echo -ne "$I\r"o print -n "$I\r". :) Ho usato printf, tuttavia, perché per impostazione predefinita non stampa una nuova riga alla fine, quindi il \rgiusto torna all'inizio. Purtroppo, non tutte le implementazioni dell'eco supportano l' argomento -eo -n.
dannysauer,

1
Funziona anche con la versione pdksh che OpenBSD utilizza per / bin / sh.
Kurtm,

1
+1, anche se per essere assolutamente corretto, dovresti cambiare readin read -r(poiché altrimenti una barra rovesciata alla fine di una riga farebbe casino con il conteggio). Per inciso, con un po 'di lavoro, questo può essere adattato per mostrare anche l'ultima linea di output, che può essere utile per alcuni comandi.
Ruakh,

7

Questa è un'idea approssimativa, ma è possibile utilizzare il pvcomando per contare il numero di righe mentre passano e visualizzarlo sullo schermo. pvtra i suoi molti switch ha un -linterruttore che conta ogni riga mentre passa.

Esempio

Qui sto usando un ciclo while per simulare alcuni file dal tuo output SVN.

$ for i in $(seq 100); do echo "file$i"; sleep 2; done | pv -l -c >/dev/null
   3 0:00:05 [0.99/s ] [      <=>             

Continuerà a sovrascrivere la linea di output in questo modo:

  18 0:00:36 [   0/s ] [                                     <=>                                                                  ]

  24 0:00:47 [0.991/s ] [                                                <=>                                                      ]

Non ero a conoscenza del pv. Evviva per imparare cose!
dannysauer,

@dannysauer - vale la pena dedicare un po 'di tempo all'apprendimento, perché consente di misurare e visualizzare tutto ciò che passa attraverso una pipe.
slm

L'ho installato dopo aver letto il commento e averlo giocato. Diciotto anni usando Linux, e ci sono ancora nuove cose da scoprire. :)
dannysauer,

0

È possibile eseguire il comando in background come lavoro e reindirizzare il suo stdout (e stderr facoltativamente) a un file di registro: command > logfile &dove &designa il lavoro (se anche stderr, dire &>invece di >).

Quindi è possibile utilizzare l'utilità di conteggio parole per contare il numero di righe nel file di registro wc -l.

Per mostrare il cambio di stato in una riga che cambia dinamicamente, potresti usare qualcosa di simile while true; do echo -en '\r'; wc -l logfile; sleep 1; done, ma non posso forzare bash a disegnare il \rritorno a capo per uccidere il contenuto della riga precedente.

Vedi questa domanda, è quasi un duplicato: /programming/2388090/how-to-delete-and-replace-last-line-in-the-terminal-using-bash


1
Ma vuole un display in tempo reale che continui ad aumentare, che non è quello che fa il WC.
Kurtm,

@kurtm eh, quello che vuole molto di più non è che il suo schermo sia inondato di risultati printf/print/echocome suggerito da Danny. :) Certo, potrebbe usare less, ma suppongo, può permettersi di dire wc -l logfileogni volta che diventa impaziente. Penso che giocare con ncurseso cancellare lo schermo sia eccessivo qui.
Boris Burkov,

Beh si. Non vuole che sia inondato, ma vuole conoscere i progressi, altrimenti potrebbe semplicemente usare il --quiet.
Kurtm,

@kurtm vedi aggiornamento: puoi aiutarmi a eseguire il debug del mio echo -e 'r'comando? Dovrebbe cancellare il contenuto della riga precedentemente stampato, in modo che cambi dinamicamente, ma non posso costringerlo a farlo :(
Boris Burkov,

Si desidera aggiungere anche l'opzione n all'eco che elimina la nuova riga finale.
Kurtm,
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.