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
"$@"