Mostra uma janela deslizante de saída de um programa

2

Eu quero executar um comando ( rsync -av ) e exibir apenas 10 linhas de saída a qualquer momento. Eu encontrei um post semelhante , mas eu não deseja redirecioná-lo para um arquivo.

Eu quero que a saída seja exibida simultaneamente, mas no máximo 10 linhas devem estar visíveis. Por exemplo: A saída tem 100 linhas, quando terminada. No começo, mostra a linha 1-10. Então 2-11 - > 3-12 - > 4-13 até 91-100

Eu tentei com:

rsync -av /source /destination | tail -f -n 10

É algo assim:

rsync -av /source /destination | while read i; do echo -en "\r$i"; done

mas com 10 linhas em vez de 1.

    
por Vince 09.01.2014 / 08:07

2 respostas

3

Eu fiz esses truques no sistema de criação de uma distribuição Linux embarcada. No meu caso, foi um pouco diferente. O script de construção restringiu a região de rolagem (via sequências de escape do VT100), de modo que o log foi mostrado nas linhas N-4 superiores do terminal. As quatro linhas inferiores foram transformadas em uma área estática que foi atualizada com o progresso da compilação: o que está sendo construído atualmente, o percentual de progresso e tal.

Uma maneira de alcançar o que você está procurando é esta:

  1. Mova o cursor para a linha inferior do terminal.
  2. Imprima dez linhas em branco para afastar qualquer material existente.
  3. Defina a região de rolagem para as dez linhas inferiores.
  4. Execute o comando.
  5. Redefinir a região de rolagem.

As seqüências de escape podem ser encontradas em inúmeras referências.

O seguinte é algo que eu acabei de bater. Ele funciona com o bash em um Ubuntu VM que tenho aqui. Ele depende de $(( ... )) aritmética e stty suportando -g para salvar as configurações de tty em uma sequência serializada. Evitei usar \e em printf para denotar o caractere de escape, o que tornaria isso menos portátil.

Interrogamos o número de linhas do terminal porque a variável LINES pode não ser exportada. (Poderíamos, em vez disso, analisar o parâmetro rows da saída de stty -a ; então poderíamos evitar toda a dança de colocar o tty no modo raw e obter a resposta do emulador de terminal usando dd . Por outro lado, esse método funciona mesmo se o valor rows do driver tty estiver incorreto.

Salve este script como, digamos, last10 , torne-o executável e tente, por exemplo, last10 find /etc .

#!/bin/bash

# save tty settings
saved_stty=$(stty -g)

restore()
{
  stty $saved_stty
  # reset scrolling region
  printf "3[1;${rows}r"

  # move to bottom of display
  printf "3[999;1H"
}

trap restore int term exit

# move to bottom of display
printf "3[999;1H"

printf "\n\n\n\n\n\n\n\n\n\n"

# Query the actual cursor position
printf "3[6n"

# read tty response
tty_response=
stty raw isig -echo
while true; do
    char=$(dd bs=1 count=1 2> /dev/null)
    if [ "$char" = "R" ] ; then
        break;
    fi
    tty_response="$tty_response$char"
done
stty $saved_stty

# parse tty_response
get_size()
{
   cols=$3
   rows=$2
}

save_IFS=$IFS
IFS='[;R'
get_size $tty_response
IFS=$save_IFS

# set scrolling region to 10 lines
printf "3[$((rows-9));${rows}r"

# move to bottom of display
printf "3[999;1H"

# run command
"$@"
    
por 29.01.2014 / 20:23
0

Você precisará manter uma contagem para poder ignorar as primeiras dez linhas:

rsync -av /source /destination | (c=0; while read i ; do if [ $c -ge 10 ]; then echo $c "$i";  fi; ((c++)); done)

o funcionamento da peça após o pipe:

(c=0; while read i ; do if [ $c -ge 10 ]; then echo $c "$i";  fi; ((c++)); done)

talvez seja mais claro se for formatado como:

c=0; 
while read i ; do 
   if [ $c -ge 10 ]; then 
      echo $c "$i";  
   fi; 
   ((c++)); 
done
    
por 09.01.2014 / 08:48