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:
- Mova o cursor para a linha inferior do terminal.
- Imprima dez linhas em branco para afastar qualquer material existente.
- Defina a região de rolagem para as dez linhas inferiores.
- Execute o comando.
- 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 "$@"