Como algumas ferramentas (por exemplo, nano, less) conseguem não deixar conteúdo nos terminais após a saída? [duplicado]

35

Sempre que eu uso um pager como less ou um editor como nano no shell (meu shell é GNU bash), vejo um comportamento que não posso explicar completamente e que difere do comportamento que posso observar com outras ferramentas como cat ou ls . Eu gostaria de perguntar como esse comportamento acontece.

O comportamento - não é fácil de explicar - é que normalmente todas as saídas para stdout / stderr acabam sendo gravadas no backbuffer de emuladores de terminal, então eu posso rolar para trás, enquanto (não tão normalmente para mim) no caso de usar less ou nano , a saída é exibida pelo emulador de terminal, mas ao sair dos programas, o conteúdo "magicamente desaparece".

Eu gostaria de dar esses dois exemplos:

  • seq 1 200 (produz 200 linhas no backbuffer)
  • seq 1 200 | less (deixa-me paginar 200 linhas, mas eventualmente "limpa" e nada é gravado no backbuffer)

Minha suspeita é que algum tipo de código de escape está em jogo e eu apreciaria alguém apontando minha explicação para essas diferenças comportamentais observadas.

Como alguns comentários e respostas são redigidos, como se fosse meu desejo mudar o comportamento, "seria bom saber", mas na verdade a resposta desejada deveria ser a descrição do mecanismo, não tanto as maneiras de alterá-lo.

    
por humanityANDpeace 11.01.2017 / 16:17

3 respostas

40

Existem duas visões de mundo aqui:

  • No que diz respeito aos programas que utilizam termcap / terminfo, o seu terminal tem potencialmente dois modos: modo de endereçamento do cursor e modo de deslocamento . O último é o modo normal, e um programa alterna para o modo de endereçamento do cursor quando precisa mover o cursor pela tela pelos endereços de linha e coluna, tratando a tela como uma entidade bidimensional.

    termcap e terminfo manipulam a tradução visão de mundo, que é o que os programas vêem, na visão de mundo vista pelos terminais.

  • No que diz respeito a um terminal (emulado ou real), existem dois buffers de tela, sendo que apenas um deles é exibido a qualquer momento. Há um buffer de tela principal e um buffer de tela alternativo . Seqüências de controle emitidas por programas alternam o terminal entre os dois.
    • Para alguns terminais, geralmente emulados, o buffer de tela alternativo é adaptado ao uso de termcap / terminfo. Eles são projetados com o conhecimento de que parte da mudança para o modo de endereçamento do cursor está alternando para o buffer de tela alternativo e parte da mudança para o modo de rolagem está mudando para o buffer de tela principal. É assim que termcap / terminfo traduz as coisas. Portanto, esses terminais não mostram widgets de interface de usuário de rolagem quando o buffer de tela alternativo está sendo exibido e simplesmente não têm mecanismo de rolagem para esse buffer de tela.
    • Para outros terminais, geralmente os reais, o buffer de tela alternativo é bem parecido com o primário. Ambos são em grande parte idênticos em termos do que eles suportam. Alguns terminais emulados se enquadram nessa classe, observe. O Unicode rxvt, por exemplo, possui um recurso de rolagem para os buffers de tela principal e alternativo.

Programas que apresentam interfaces de usuário textuais de tela inteira (como vim , nano , less , mc e assim por diante) usam termcap / terminfo para alternar para o cursor -addressing mode na inicialização e volta ao modo de rolagem quando eles são suspensos, ou saem ou saem. A biblioteca ncurses faz isso, mas também programas que não utilizam ncurses, que constroem mais diretamente sobre termcap / terminfo.

A rolagem nas TUIs apresentada por less ou vim não tem nada a ver com a rolagem. Isso é implementado dentro desses programas, que estão apenas redesenhando sua interface de usuário em texto em tela cheia, conforme apropriado, conforme as coisas rolam.

Observe que esses programas não "não deixam conteúdo" no buffer de tela alternativo. O terminal simplesmente não está mais mostrando o que eles deixam para trás.

  • Isso é particularmente notado com o Unicode rxvt em algumas plataformas, em que as sequências termcap / terminfo para alternar para o modo de endereçamento do cursor não limpam implicitamente o buffer de tela alternativo. Portanto, usar múltiplos programas TUI em tela cheia sucessivamente pode acabar exibindo o conteúdo antigo do buffer de tela alternativo deixado pelo último programa, pelo menos por um tempo até que o novo programa grave sua saída (mais notório quando less está no final de um pipeline).
  • Com o xterm, pode-se alternar para exibir o buffer de tela alternativo no menu GUI do emulador de terminal e ver o conteúdo ainda presente.

As sequências de controle reais são o que os padrões relevantes chamam de seqüências de controle do modo privado definido. Os números de modo privado relevantes são 47, 1047, 1048 e 1049. Observe as diferenças em quais ações extras são implícitas por cada um, além de alternar para / do buffer de tela alternativo.

Leitura adicional

por 11.01.2017 / 18:06
5

Uma biblioteca chamada curses, sabe qual tipo de terminal você está usando e envia as seqüências de escape corretas. Lá terminal é solicitado a mudar para um buffer vertical diferente, e modo que permite mais controle.

    
por 11.01.2017 / 16:47
4

Você pode adicionar um claro para isso de duas maneiras. Você pode resolver less da limpeza da tela chamando-a com o argumento -X .

Observe o símbolo $ nas linhas de comando abaixo. Isso está especificando o prompt do terminal de um usuário normal.

$ seq 1 200 | less -X

Se esse é o seu comportamento desejado, você pode alias less para esse padrão com:

$ alias less='less -X'

Existem soluções alternativas semelhantes para outros programas.

Como alternativa, em vez de tentar configurar cada aplicativo individualmente, você pode adicionar sua própria definição de terminal. Nesse caso, chamarei de xterm-noclear para este exemplo.

Execute estas etapas para criar uma nova definição de xterm:

$ infocmp -I xterm > xterm-noclear.src
$ gedit xterm-noclear.src

Agora, altere a segunda linha do seu editor de xterm para xterm-noclear .

Remova as instruções que limpam a tela pesquisando rmcup e smcup e removendo estas duas instruções:

smcup=\E[?1049h,

e

rmcup=\E[?1049l, 

Salve o arquivo e adicione a definição do terminal com:

$ tic ~/xterm-noclear.src

Você pode tornar isso uma definição de terminal disponível em todo o sistema com:

$ sudo tic ~/xterm-noclear.src

Agora você pode usar este TERM com:

$ export TERM=xterm-noclear
    
por 11.01.2017 / 17:25