Como exibir o número de linhas emitidas por um comando em tempo real?

15

Estou usando svn exportcomo parte de um script de empacotador para o meu aplicativo e parece que esse comando, como muitos outros, não possui nenhum tipo de barra de progresso.

Eu tenho duas opções no momento:

  • usando-o sem opções e assista a milhares de linhas de impressão
  • usando --quiete não vendo nada até que seja concluído.

Existe uma maneira de, pelo menos, mostrar o número de linhas emitidas pelo comando, em tempo real? Tal como:

Exporting SVN directory ... 1234 files

E vê esse 1234 incremento de número em tempo real ? Eu posso imaginar canalizando a saída para um comando que faria exatamente isso, mas qual?

Benjamin
fonte

Respostas:

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

Ou coloque a seção entre colchetes em um script de shell. Observe que isso só funciona se o seu shell realmente suportar o operador de pré-incremento, como bash ou ksh93 ou zsh. Caso contrário, você terá que incrementar $Ie imprimi-lo (como em I=$((I+1));printf...). Além disso, se printfnão houver um built-in com seu shell (é um built-in com o bash atual), você poderá usar echo -neou, em print -nvez disso, obter um melhor desempenho. Você só quer suprimir a nova linha e ter o \ r interpretado como um caractere de escape.

dannysauer
fonte
Ah, nunca vou me obrigar a aprender bashscripting com todas as suas =diferenças e peculiaridades feias e `=`. :) Por que eles não substituí-lo com a linguagem Python como-syntaxed ...
Boris Burkov
Ei, eu sei o que! Você pode adicionar o símbolo de retorno de carro a cada nova linha impressa, e não inundará a tela, apenas substituirá a linha anterior.
Boris Burkov #
É por isso que printftermina com a \r. E o que acontece se você fizer echo -ne "$I\r"ou print -n "$I\r". :) Eu usei printf, no entanto, porque o padrão é não imprimir uma nova linha no final, então o \rretorno é apenas o começo. Infelizmente, nem todas as implementações de eco suportam o argumento -eou -n.
22613 Dannysauer
1
Isso também funciona com a versão pdksh que o OpenBSD usa para / bin / sh.
Kurtm # 6/13
1
+1, embora seja absolutamente correto, você deve alterar readpara read -r(pois, caso contrário, uma barra invertida no final de uma linha interferiria na contagem). Aliás, com um pouco de trabalho, isso pode ser adaptado para mostrar também a última linha de saída, que pode ser útil para alguns comandos.
Ruakh 07/10
7

Essa é uma idéia aproximada, mas você pode usar o pvcomando para contar o número de linhas conforme elas passam e exibi-las na tela. pvdentre seus muitos switches, há um -lswitch que conta cada linha à medida que passa.

Exemplo

Aqui estou usando um loop while para simular alguns arquivos da sua saída 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 ] [      <=>             

Ele continuará substituindo a linha de saída assim:

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

  24 0:00:47 [0.991/s ] [                                                <=>                                                      ]
slm
fonte
Eu não tinha conhecimento do pv. Viva para aprender coisas!
22613 Dannysauer
@dannysauer - vale a pena gastar algum tempo aprendendo, pois permite que qualquer coisa que passe por um cano seja aferida e exibida.
slm
Eu o instalei depois de ler o comentário e brincar com ele. Dezoito anos usando o Linux, e ainda há sempre coisas novas para descobrir. :)
dannysauer
0

Você pode executar seu comando em segundo plano como um trabalho e redirecionar seu stdout (e stderr opcionalmente) para um arquivo de log: command > logfile &onde &designa job (se stderr também, digamos em &>vez de >).

Então você pode usar o utilitário wordcount para contar o número de linhas em seu arquivo de log wc -l.

Para mostrar a mudança de estado em uma linha que muda dinamicamente, você pode usar algo como while true; do echo -en '\r'; wc -l logfile; sleep 1; done, mas eu não posso forçar o bash a desenhar \rretorno de carro para eliminar o conteúdo da linha anterior.

Veja esta pergunta, é quase uma duplicata: /programming/2388090/how-to-delete-and-replace-last-line-in-the-terminal-using-bash

Boris Burkov
fonte
1
Mas ele quer uma exibição em tempo real que continue aumentando, o que não é o que a wc faz.
kurtm
@kurtm eh, o que ele quer muito mais é não deixar sua tela cheia de resultados printf/print/echosugeridos por danny. :) É claro que ele poderia usar less, mas suponho que ele pode dizer wc -l logfilesempre que fica impaciente. Eu acho que brincar com ncursesou limpar a tela é um exagero aqui.
Boris Burkov 06/10
Bem, sim. Ele não quer que seja inundado, mas ele quer conhecer o progresso, caso contrário, ele poderia simplesmente usar o --quiet.
Kurtm # 6/13
@kurtm see update: você pode ajudar a depurar meu echo -e 'r'comando? Deve apagar o conteúdo impressas anteriormente de linha, de modo que muda dinamicamente, mas não posso forçá-lo a fazer isso :(
Boris Burkov
Você também deseja adicionar a opção n ao eco, que suprime a nova linha à direita.
Kurtm # 6/13