Como rolar o cursor no terminal para imprimir uma string?

2

Aqui eu quero algo como a forma que o aircrack-ng faz para exibir texto na tela do terminal, ou como scripts de matriz ...!

Por exemplo, se a minha tela de terminal já contiver 4 linhas, eu quero atualizar a 1ª dessas primeiras linhas em seu lugar, e a mesma para outras linhas ... (usando o bash)

Para ser mais preciso, quero um script como o seguinte:

#!/bin/bash
while :
  do
    echo "line1"
    echo "line2"
    echo "line3"
    echo "line4"
    # without using clear cmd, next cycle line1 should be printed
    # in line1 place not in a new line , and same for other lines
  done
    
por Jonas 10.11.2015 / 16:26

2 respostas

10

Nos terminais compatíveis, você pode usar tput sc para salvar a posição do cursor e tput rc para restaurá-lo:

i=0
tput sc
while sleep 1; do
  tput rc
  echo "line$((i=i+1))"
  echo "line$((i=i+1))"
  echo "line$((i=i+1))"
  echo "line$((i=i+1))"
done

Vocêpodesalvaressasseqüênciasdeescapeemumavariávelparaevitarterqueinvocartputtodasasvezes:

rc=$(tputrc)||echo>&2"Warning: terminal doesn't support restoring the cursor"
...
printf '%s\n' "${rc}line1..."

Nos terminais raros que não suportam, você sempre pode usar seqüências de posicionamento do cursor,

while sleep 1; do
  echo "line$((i=i+1))"
  echo "line$((i=i+1))"
  echo "line$((i=i+1))"
  echo "line$((i=i+1))"
  tput cuu 4 # or up=$(tput cuu1); printf %s "$up$up$up$up"
done

Veja a página terminfo man na seção 5 (se o seu sistema vier com ncurses) para mais detalhes.

    
por 10.11.2015 / 16:38
3

Eu respondi isso no StackOverflow há alguns meses, veja Sobrescrevendo a última saída de terminal ( várias linhas) . Embora eu suponha que seja possível que OP tenha sido escrito literalmente "line1", "line2", etc., isso seria de interesse apenas em um exercício em sala de aula. Programas reais imprimem coisas mais interessantes, então estou respondendo essa pergunta. Como antes, o q / a atual ignora o problema quando as linhas atualizadas são mais curtas do que a linha existente. Endereçando isso

#!/bin/bash
tput sc
while :
  do
    tput rc
    echo "line1"; tput el
    echo "line2"; tput el
    echo "line3"; tput el
    echo "line4"; tput el
    # without using clear cmd, next cycle line1 should be printed
    # in line1 place not in a new line , and same for other lines
  done
Concordando que cuu é uma boa alternativa, usar grep para verificar a disponibilidade de um recurso parece menos eficaz do que usar tput , por exemplo,

restore=$(tput sc)
[[ -z "$restore" ]] && restore=$(tput cuu 4)
[[ -z "$restore" ]] && restore=$(tput cuu1; tput cuu1; tput cuu1; tput cuu1)

que ainda é um pouco grosseiro na forma como o número de linhas é incorporado nas expressões. Mas então você poderia simplesmente executar $restore no final do loop.

Algo similar pode ser feito com a verificação de el no terminal.

Considerando que isso é bash, o echo "line1" , etc., deve realmente ser uma função (o que eliminaria as chamadas tput el redundantes).

Todos esses recursos provavelmente serão suportados com terminais que o OP provavelmente encontrará. Os controles do cursor salvar / restaurar são um ponto fraco, já que existem duas variantes principais:

  • DECSC / DECRC (suportado pelo xterm - consulte Sequências de Controle XTerm :

    ESC 7     Save Cursor (DECSC).
    ESC 8     Restore Cursor (DECRC).
    
  • ANSI.SYS (também suportado pelo xterm, mas não por todos os "emuladores xterm"):

    CSI s     Save cursor (ANSI.SYS), available only when DECLRMM is disabled.
    CSI u     Restore cursor (ANSI.SYS).
    

Outras fontes úteis de informação:

A propósito, a pergunta é incorreta, já que o exemplo dado (e até agora nenhuma das respostas) usa rolagem . Pode-se (referindo-se novamente ao terminfo e limitando-se a terminais do tipo VT100, como o xterm), usar regiões de rolagem. O lugar para começar seria aqui (a partir da página de manual do terminfo):

   change_scroll_region          csr        cs        change region to      
                                                      line #1 to line #2    
                                                      (P)   
    
por 10.11.2015 / 23:28

Tags