Posso sobregravar várias linhas de stdout na linha de comando sem perder a rolagem do terminal?

1

Gostaria de criar várias barras de progresso e atualizá-las em qualquer lugar, sem a necessidade de limpar a tela inteira (gostaria que o conteúdo stdout anterior permanecesse na tela).

Eu preciso:

  1. Escreva algumas linhas com echo
  2. Espere com sleep
  3. Coloque meu cursor de volta no início da primeira linha
  4. Substituir minhas poucas linhas por informações atualizadas
  5. Repita a partir do passo 2.

O pensamento é que eu gostaria que o usuário pudesse rolar de volta para ler o conteúdo do stdout anterior.

Se eu não me importasse com o pergaminho, usaria apenas clear e escrevesse novamente o que eu preciso:

while [ true ]; do echo "$SECONDS"; sleep 0.1; clear; done

Isso, no entanto, torna a rolagem completamente ilegível, porque clear simplesmente imprime novas linhas suficientes para empurrar a saída de terminal anterior para fora da vista.

Quando eu corro htop e fecho - ele restaura meu terminal exatamente no mesmo estado em que ele começou. Pode algo assim ser alcançado em um script bash?

    
por unfa 20.04.2017 / 16:12

1 resposta

2

Use tput sc tput ed e tput rc .

De manual de transferência :

tput sc

Save the cursor position

tput rc

Restore the cursor position

tput ed

Clear to end of screen

Exemplo:

tput sc; while [ true ]; do tput ed; echo -e "$SECONDS\n$SECONDS\n$SECONDS"; sleep 1; tput rc; done

Como funciona?

  1. Armazena a posição do cursor com tput sc
  2. Insere o loop que atualizará as informações na tela
  3. tput ed limpa até o final da tela para garantir resultado adequado
  4. Então, as várias linhas de alteração de dados são gravadas com echo
  5. sleep 1 espera um segundo antes de atualizar
  6. tput rc move o cursor de volta para o começo das linhas que acabamos de imprimir
  7. loop repete sobrescrevendo com novas informações
por 20.04.2017 / 16:12