Outro dia eu estava desenvolvendo um programa para o GNU/Linux em modo texto e esse programa executaria algumas operações e deveria exibir o status dessa execução no terminal. Pois bem, foi aí que me deparei com algumas características interessantes do famoso "modo texto" do GNU/Linux. Acabei tropeçando também em muita história interessante que gostaria de compartilhar.

Na verdade o correto não é modo texto, mas sim "Terminal". Terminal, Modo Texto, TTY? What the Hell?

Terminais Burros - São chamados assim porque de nada servem se não estão em conexão com um servidor. Nenhum processo é executado no terminal, mas sim no servidor. No Terminal Burro temos apenas a entrada de dados (via teclado) e a saída ou retorno de dados (via monitor). Existem também Terminais Gráficos que exibem imagens, o X11 é um servidor de terminais gráficos usados para enviar imagens à terminais gráficos.

Sistemas operacionais padrão Unix (como o GNU/Linux e o FreeBSD) possuem consoles virtuais para fornecer vários terminais de texto em um único computador. A principal função do terminal de texto é de interpretador de linha de comando (ou shell), que interpreta os comandos do usuário, executa cada comando e então retorna informações.

Agora que conhecemos um pouco da história dos TTY, vamos ver um pouco das características do TTY. Vamos imaginar um programa em C desenvolvido para GNU/Linux, que irá executar em modo texto. Esse programa irá executar algumas operações e gostaríamos de ter um feedback afim de saber em que passo estamos e quanto falta para terminar. Então podemos considerar o seguinte programa:

A Herança do TTY

Agora vamos perceber o seguinte: Muito foi herdado dos terminais TTY, como os caracteres de controle por exemplo.

No nosso programa exemplo o ideal é mover o cursor para o início da mesma linha a cada passo que o programa atualize o status. Usaremos o caractere especial Carriage Return (CR). No C ele é representado pelo \r .

Você deve conhecer o caractere especial chamado Line Feed (LF). No C ele é representado pelo

e serve para mover o cursor para a próxima linha. Veja que ele está presente no nosso programa no comando printf . Vamos atualizar nosso programa, removendo o

no final da string do printf e incluindo o \r no início.

#include <stdio.h> int main ( void ) { int status ; for ( status = 1 ; status <= 100 ; status ++ ) { printf ( " \r Processando - %u%%" , status ); // Operacoes do programa for ( d1 = 1 ; d1 <= 6500 ; d1 ++ ) for ( d2 = 1 ; d2 <= 6500 ; d2 ++ ); // Tarefa DUMMY - Apenas para consumir tempo e simular funcionamento. } printf ( "

Finalizado!

" ); }

Pela lógica tudo nos parece bem. Agora vamos ter a atualização do status na mesma linha. Vamos testar? Vai lá… Compile e execute o código. Eu espero.

Ei! O que está acontecendo? O programa está estranho… lá pelos 63% que tivemos a primeira atualização de tela e logo depois o programa terminou. Mas afinal, o que aconteceu aqui?

Bem, o que aconteceu aqui não pode ser chamado de erro, mas sim de característica. Explico: Do mesmo modo que herdamos os caracteres de controle como o Carriage Return (CR) e o Line Feed (LF), herdamos algumas outras características como a velocidade dos terminais e o conceito de buffer de dados. A atualização de dados do nosso programa foi mais rápido do que o terminal, e por isso pouco vimos da execução do nosso programa.

Para ver qual é a velocidade do nosso terminal podemos usar o comando stty do GNU/Linux. Este comando é usado para alterar ou exibir as configurações do terminal.