Algumas palavras do nosso escritório de tradução: geralmente todos se esforçam para traduzir os materiais e publicações mais recentes, e não somos a exceção. No entanto, os terminais não são algo que se atualiza toda semana. Por isso, traduzimos para você o artigo de Antoine Bopré, publicado na primavera de 2018: apesar de sua idade considerável para os padrões atuais, acreditamos que o material não perdeu relevância. Além disso, o original é uma série de dois artigos, mas decidimos combiná-los em um grande post.

Os terminais ocupam um lugar especial na história da computação, mas nas últimas décadas eles foram obrigados a sobreviver junto com a linha de comando, em meio à proliferação de interfaces gráficas. substituíram seus , que, por sua vez, eram modificações de sistemas baseados em cartões perfurados e comutadores. Distributivos modernos vêm com uma infinidade de emuladores de terminal de todas as formas e cores. Enquanto muitos se contentam com o terminal padrão fornecido pelo seu ambiente de trabalho, alguns orgulhosamente utilizam softwares exóticos para rodar seus shells favoritos ou editores de texto. Mas, como veremos neste artigo, nem todos os terminais foram criados da mesma forma: eles diferem significativamente em funcionalidade, tamanho e desempenho.
Alguns terminais apresentam falhas de segurança bastante surpreendentes, além de a maioria ter conjuntos de funcionalidades completamente diferentes, desde suporte a interfaces com abas até scripts. Embora nós , este artigo é uma atualização do material anterior, que ajudará os leitores a determinar qual terminal usar em 2018. Na primeira metade do artigo, comparamos as funcionalidades, enquanto na segunda avaliamos o desempenho.
Aqui estão os terminais que eu examinei:

Talvez estas não sejam as versões mais recentes, uma vez que me limitei a compilações estáveis no momento em que escrevi este material, que consegui instalar no Debian 9 ou Fedora 27. A única exceção é o Alacritty. Ele é um descendente de terminais com aceleração por GPU e foi escrito em uma linguagem incomum e nova para essa tarefa — Rust. Excluí da minha análise os terminais baseados na web (inclusive, na ), pois testes preliminares mostraram desempenho extremamente baixo.
Suporte a Unicode
Comecei meus testes com suporte a Unicode. O primeiro teste dos terminais foi a exibição de uma linha sobre Unicode de : "é, Δ, Й, ק, م, ๗, あ, 叶, 葉 e 말". Este simples teste mostra se o terminal pode funcionar corretamente em todo o mundo. O terminal xterm não exibe o caractere árabe na configuração padrão:

Por padrão, o xterm usa uma fonte "fixa" clássica, que, segundo , tem "abrangência substancial em Unicode desde 1997". Nesta fonte, algo acontece que faz o caractere aparecer como uma caixa vazia e só quando aumento o tamanho do texto para 20+ pontos o caractere finalmente começa a aparecer corretamente. No entanto, esse "conserto" quebra a exibição de outros caracteres Unicode:

Essas capturas de tela foram feitas no Fedora 27, pois este sistema ofereceu os melhores resultados em comparação ao Debian 9, onde algumas versões mais antigas dos terminais (especificamente — mlterm) não puderam funcionar corretamente com as fontes. Felizmente, isso foi corrigido em versões posteriores.
Agora, observe a exibição da linha no xterm. Aparentemente, o caractere Mem e o seguinte Semitic pertencem a scripts de escrita RTL (), portanto, tecnicamente, eles devem ser exibidos da direita para a esquerda. Navegadores da web, como o Firefox 57, processam corretamente a linha acima. Uma variante mais simples de texto RTL é a palavra "" em hebraico (). diz o seguinte:
"Muitos programas de computador têm dificuldade em exibir corretamente texto bidirecional. Por exemplo, o nome hebraico 'Sará' consiste nos caracteres sin (ש) (que aparece à direita), seguido de resh (ר) e, finalmente, hei (ה) (que deve aparecer à esquerda)".
Muitos terminais não passam neste teste: Alacritty, terminais derivados do VTE do Gnome e XFCE, urxvt, st e xterm exibem "Sara" ao contrário, como se estivéssemos escrevendo esse nome como "Aras".

Outro problema dos textos bidirecionais é que eles precisam ser alinhados de alguma forma, especialmente quando se trata da mistura de textos RTL e LTR. Scripts RTL devem começar do lado direito da janela do terminal, mas o que deve acontecer para terminais que, por padrão, funcionam com inglês LTR? A maioria deles não possui mecanismos especiais e alinha todo o texto à esquerda (incluindo no Konsole). A exceção são pterm e mlterm, que seguem os padrões e alinham essas linhas à direita.

Proteção contra inserção
A próxima característica crítica que defini para mim é a proteção contra inserção. Embora seja amplamente conhecido que feitiços como:
$ curl http://example.com/ | shsão comandos de execução de código, poucos sabem que comandos ocultos podem penetrar no console ao copiar e colar de um navegador, mesmo após cuidadosa inspeção. mostra brilhantemente como um comando que parece inofensivo:
git clone git://git.kernel.org/pub/scm/utils/kup/kup.gitse transforma, ao ser colado do site de Horn para o terminal, em algo bastante problemático:
git clone /dev/null;
clear;
echo -n "Hello ";
whoami|tr -d 'n';
echo -e '!nEssa foi uma má ideia. Não copie código de sites nos quais você não confia!
Aqui está a primeira linha do seu /etc/passwd: ';
head -n1 /etc/passwd
git clone git://git.kernel.org/pub/scm/utils/kup/kup.gitComo isso funciona? O código malicioso é colocado em um bloco , que é movido fora da vista do usuário através de CSS.
é explicitamente projetado para neutralizar tais ataques. Nesse modo, terminais envolvem o texto colado em um par de sequências de escape especiais para informar ao shell sobre a origem desse texto. Assim, o shell recebe o sinal de que pode ignorar caracteres especiais que podem estar presentes no texto colado. Todos os terminais, até o respeitável xterm, suportam essa função, mas a colagem no modo com colchetes necessita do suporte do shell ou do aplicativo executado no terminal. Por exemplo, o software que usa (o mesmo Bash), precisa de um arquivo ~ /.inputrc:
set enable-bracketed-paste onInfelizmente, o site de testes do Horn também demonstra como contornar essa proteção por meio da própria formatação do texto e finalizar prematuramente a aplicação do modo Bracketed. Isso funciona porque alguns terminais filtram incorretamente as sequências de escape antes de adicionar as suas próprias. Por exemplo, eu não consegui concluir com sucesso os testes do Konsole, mesmo considerando a configuração correta. .inputrc de arquivo. Isso significa que você pode facilmente causar danos à configuração do sistema devido a um aplicativo não suportado ou a um shell mal configurado. Isso é particularmente perigoso ao acessar servidores remotos, onde uma configuração bem elaborada é menos comum, especialmente se você tiver muitas dessas máquinas remotas.
Uma boa solução para esse problema é o plugin de confirmação de colagem para terminais urxvt, que simplesmente solicita permissão para colar qualquer texto que contenha novas linhas. Não encontrei uma opção mais segura para a ataque textual descrito pelo Horn.
Guias e perfis
Um recurso popular atualmente é o suporte à interface com guias, que definiremos como uma única janela de terminal que contém vários terminais. Para diferentes terminais, essa função varia, e embora terminais tradicionais como o xterm não suportem guias, as encarnações mais modernas, como Xfce Terminal, GNOME Terminal e Konsole, possuem tal função. O Urxvt também suporta guias, mas apenas com o uso de um plugin. No entanto, em termos de suporte a guias, o líder absoluto é o Terminator: ele não apenas suporta guias, mas também pode dispor os terminais em qualquer ordem (veja a imagem abaixo).

Outra característica do Terminator é a capacidade de "agrupar" essas guias juntas e enviar as mesmas combinações de teclas para vários terminais ao mesmo tempo, o que fornece uma ferramenta rudimentar para executar operações em massa em vários servidores simultaneamente. Uma função semelhante também está presente no Konsole. Para usar essa função em outros terminais, é necessário recorrer a software de terceiros, como , ou .
As abas funcionam especialmente bem em conjunto com perfis: por exemplo, você pode ter uma aba para e-mail, outra para chat e assim por diante. Isso é bem suportado pelo terminal Konsole e pelo GNOME Terminal. Ambos permitem que cada aba inicie automaticamente seu perfil. O Terminator também suporta perfis, mas não consegui encontrar uma maneira de iniciar automaticamente programas específicos ao abrir uma aba determinada. Outros terminais não têm ideia do que é um 'perfil'.
Babados
A última coisa que vou considerar na primeira parte deste artigo é a aparência dos terminais. Por exemplo, GNOME, Xfce e urxvt suportam transparência, mas recentemente retiraram o suporte para imagens de fundo, o que levou alguns usuários a mudarem para outro terminal. . Pessoalmente, estou satisfeito e é simples. Xresources, que define um conjunto básico de cores de fundo para urxvt. No entanto, temas de cores não padronizados podem causar problemas. Por exemplo, com aplicativos e , uma vez que já usam suas próprias cores.
não suportava cores, e os novos muitas vezes eram limitados a uma paleta de 256 cores. Para usuários avançados que estilizam seus terminais, as solicitações de shell ou as barras de estado de maneiras complexas podem se tornar uma limitação inconveniente. monitora quais terminais têm suporte para 'True Color'. Meus testes confirmam que st, Alacritty e terminais baseados em VTE suportam perfeitamente True Color. Outros terminais não se saem bem nesse aspecto e, na verdade, nem exibem 256 cores. Abaixo você pode ver a diferença entre o suporte a True Color nos terminais GNOME, st e xterm, que lidam bem com essa tarefa com sua paleta de 256 cores, e urxvt, que não só não passa no teste, mas também exibe alguns símbolos piscantes em vez deles.

Alguns terminais também analisam texto em busca de padrões de URL para tornar links clicáveis. Isso se aplica a todos os terminais derivados de VTE, enquanto urxvt requer um módulo plug-in específico que transforme URLs em cliques ou por meio de uma combinação de teclas. Outros terminais que testei exibem URLs de maneiras diferentes.
Finalmente, a nova tendência dos terminais é a opção de buffer de rolagem. Por exemplo, no st não há buffer de rolagem; presume-se que o usuário usará um multiplexador de terminal, como o tmux e .
No Alacritty, também não há buffers de rolagem reversa, mas devido ao "extenso feedback" sobre esse tópico por parte dos usuários. Além desses, cada terminal que verifiquei tinha suporte à rolagem reversa.
Resultados intermediários
Na segunda parte do material (originalmente eram dois artigos diferentes — nota do tradutor.) vamos comparar o desempenho, o uso de memória e a latência. Mas já vemos que alguns dos terminais analisados têm sérias desvantagens. Por exemplo, usuários que trabalham regularmente com scripts RTL podem se interessar pelo mlterm e pterm, pois eles lidam melhor com essas tarefas. O Konsole também se destacou. Usuários que não trabalham com scripts RTL podem optar por outra opção.
Do ponto de vista da proteção contra a inserção de código malicioso, o urxvt se destaca devido à sua implementação especial de proteção contra esse tipo de ataque, que me parece definitivamente conveniente. Aqueles que procuram recursos adicionais devem considerar o Konsole. Por fim, é importante mencionar que o VTE é uma excelente base para terminais, garantindo suporte a cores, reconhecimento de URL e assim por diante. À primeira vista, o terminal padrão fornecido com seu ambiente favorito pode atender a todas as necessidades, mas deixaremos essa questão em aberto até analisarmos o desempenho.
Continuando a conversa
No geral, o desempenho dos terminais pode parecer uma questão exagerada, no entanto, descobriu-se que alguns deles demonstram uma latência surpreendentemente alta para um software de natureza tão fundamental. Também discutiremos o que tradicionalmente é chamado de "velocidade" (na verdade, essa é a velocidade de rolagem) e o consumo de memória do terminal (considerando que hoje isso não é tão crítico como décadas atrás).
Latência
Após uma pesquisa minuciosa sobre o desempenho dos terminais, cheguei à conclusão de que o parâmetro mais importante nesse aspecto é o tamanho da latência (ping). Em meu artigo Pavel Fatin analisou a latência de vários editores de texto e sugeriu que os terminais podem funcionar mais lentamente do que os editores de texto mais rápidos. Essa sugestão me levou, afinal, a iniciar meus próprios testes e escrever este artigo.
Mas o que é latência e por que é tão importante? Em seu artigo, Fatin definiu-a como "a latência entre pressionar a tecla e a correspondente atualização na tela" e citou , que afirma: "A latência na retroalimentação visual na tela do computador tem um impacto significativo no comportamento do digitador e sua satisfação."
Fatin explica que essa latência tem consequências mais profundas do que apenas a satisfação: "digitar se torna mais lento, ocorrem mais erros, e a tensão nos olhos e músculos aumenta." Em outras palavras, uma maior latência pode resultar em erros de digitação, assim como na redução da qualidade do código, pois aumenta a carga cognitiva no cérebro. Mas o que é ainda pior, a latência "aumenta a tensão nos olhos e músculos", o que aparentemente implica futuramente (aparentemente, o autor se refere a problemas com os músculos dos olhos, costas, mãos e, claro, visão – nota da tradução.) devido à tensão repetida.
Alguns desses efeitos são conhecidos há muito tempo, e os resultados , publicados em 1976 na revista Ergonomics, indicam que uma latência de 100 milissegundos "reduz significativamente a velocidade de digitação". Recentemente, no manual do usuário GNOME, foi introduzido de 10 milissegundos, e se formos além, mostra que o ideal é de 1 milissegundo.
Fatin realizou seus testes em editores de texto; ele criou uma ferramenta portátil chamada , que eu usei para verificar o ping em emuladores de terminal. Lembre-se de que o teste foi realizado em modo de simulação: na realidade, precisamos considerar também a latência de entrada (teclado, controlador USB etc.) e de saída (buffer da placa de vídeo, monitor). Segundo Fatina, em configurações típicas, essa latência é de cerca de 20 ms. Com equipamentos voltados para gamers, é possível alcançar apenas 3 milissegundos. Como já temos esse tipo de equipamento rápido, o aplicativo não deve adicionar mais latência. O objetivo de Fatina é reduzir a latência do aplicativo para 1 milissegundo ou até mesmo alcançar um conjunto sem , como em .
Aqui estão os resultados das minhas medições, assim como alguns resultados de Fatina, para mostrar que meu experimento está em conformidade com seus testes:

A primeira coisa que me impressionou foi o melhor tempo de resposta em programas mais antigos, como xterm e mlterm. Com uma latência de registro pior (2,4 ms), eles mostraram resultados melhores do que o terminal moderno mais rápido (10,6 ms para st). Nenhum terminal moderno fica abaixo do limite de 10 milissegundos. Em particular, o Alacritty não atende aos requisitos de 'o mais rápido de todos os emuladores de terminal existentes', embora seus resultados tenham melhorado desde a primeira verificação em 2017. De fato, os autores do projeto e estão trabalhando na melhoria da exibição. Também é importante notar que o Vim, que usa GTK3, é consideravelmente mais lento do que seu equivalente GTK2. Isso leva à conclusão de que o GTK3 cria uma latência adicional, refletindo-se em todos os outros terminais que o usam (Terminator, Xfce4 Terminal e GNOME Terminal).
No entanto, as diferenças podem ser imperceptíveis para o olho. Como explica Fatina: 'não é necessário perceber a latência para que ela tenha efeito sobre você'. Fatina também alerta sobre a variabilidade: 'qualquer discrepância na duração da latência (tremulação) gera uma carga adicional devido à sua imprevisibilidade'.

O gráfico acima foi obtido em um Debian 9 puro (stretch) com . Este ambiente oferece os melhores resultados nos testes de latência. Descobriu-se que o GNOME adiciona um ping extra de 20 ms para todas as medições. Uma possível explicação para isso é a presença de programas com processamento síncrono de eventos de entrada. Fatin dá um exemplo disso , que adiciona latência ao processar todos os eventos de entrada de forma síncrona. Por padrão, o GNOME também vem com um gerenciador de janelas , que cria um nível adicional de buffer, o que afeta o ping e adiciona pelo menos 8 milissegundos de latência.

Velocidade de Rolar
O próximo teste é uma verificação tradicional de "velocidade" ou "largura de banda", que mede quão rapidamente o terminal pode rolar pela página, exibindo uma grande quantidade de texto na tela. A mecânica do teste varia; o teste original consistia simplesmente em gerar a mesma linha de texto usando o comando seq. Outros testes envolvem a verificação de Thomas E. Dick (que acompanha o xterm), onde um arquivo terminfo.src é Em outra revisão de desempenho de terminais, usa uma string de bytes aleatórios em codificação base32, que é exibida no terminal usando cat. Liu considera esse teste "um benchmark tão inútil quanto se pode imaginar" e sugere usar a resposta do terminal como o principal indicador. Dick também considera seu teste enganoso. No entanto, ambos os autores reconhecem que a largura de banda da janela do terminal pode ser um problema. Liu descobriu um travamento no Emacs Eshell ao exibir arquivos grandes, enquanto Dick otimizou o terminal para eliminar a lentidão visual do xtrerm. Portanto, ainda há algum valor neste teste, mas como o processo de renderização varia significativamente de terminal para terminal, ele pode ser utilizado como um componente de teste para verificar outros parâmetros.

Aqui vemos que rxvt e st se destacam em relação aos concorrentes, seguidos pelo muito mais novo Alacritty, desenvolvido com foco em desempenho. Em seguida, vêm Xfce (família VTE) e Konsole, que funcionam quase duas vezes mais rápido. Por último, xterm apresenta-se com uma velocidade cinco vezes menor que a do rxvt. Durante o teste, o xterm também apresentou um tremido significativo, tornando difícil visualizar o texto que passava, mesmo que fosse a mesma linha. O Konsole mostrou-se rápido, mas às vezes 'trapaceava': a tela travava de vez em quando, exibindo texto parcialmente ou não mostrando nada. Outros terminais apresentaram linhas com clareza, incluindo st, Alacritty e rxvt.
Diki explica que as diferenças de desempenho estão relacionadas ao design dos buffers de rolagem em diferentes terminais. Em particular, ele culpa o rxvt e outros terminais por 'não seguirem as regras gerais':
«Ao contrário do xterm, o rxvt não tentou exibir todas as atualizações. Se ele fica atrasado, ele descarta algumas atualizações para recuperar o tempo. Isso teve um impacto maior na velocidade aparente da rolagem do que na organização da memória interna. Uma desvantagem foi que a animação ASCII era um tanto imprecisa».
Para corrigir essa aparente lentidão do xterm, Diki sugere usar o recurso , que permite ao xterm descartar algumas atualizações de tela para não ficar para trás no fluxo. Meus testes confirmam que o fastScroll melhora o desempenho e coloca o xterm em um nível semelhante ao do rxvt. No entanto, é uma solução bastante rudimentar, como explica o próprio Diki: 'às vezes o xterm — assim como o konsole — parece parar enquanto espera um novo conjunto de atualizações de tela depois que algumas delas foram descartadas'. Nesse sentido, parece que outros terminais encontraram o melhor compromisso entre velocidade e integridade da exibição.
Consumo de recursos
Independentemente da viabilidade de considerar a velocidade de rolagem como um indicador de desempenho, este teste permite simular a carga nos terminais, o que, por sua vez, nos permite medir outros parâmetros, como uso de memória ou disco. As métricas foram obtidas ao executar o teste indicado seq sob monitoramento do processo Python. Ele coletava dados dos contadores para ru_maxrss, a soma de ru_oublock e ru_inblock e um cronômetro de tempo.

Neste teste, o ST ocupa o primeiro lugar com o menor consumo médio de memória, de 8 MB, o que não é surpreendente, considerando que a principal ideia do projeto é a simplicidade. O mlterm, xterm e rxvt consomem um pouco mais — cerca de 12 MB. Outro resultado notável é o Alacritty, que requer 30 MB para funcionar. Em seguida, temos os terminais da família VTE com consumos variando de 40 a 60 MB, o que é bastante. Esse consumo pode ser explicado pelo fato de que esses terminais utilizam bibliotecas de nível mais alto, como o GTK. O Konsole fica por último, com um consumo colossal de 65 MB durante os testes, embora isso possa ser justificado por seu conjunto bastante amplo de recursos.
Comparado aos resultados anteriores obtidos há dez anos, todos os programas passaram a consumir significativamente mais memória. Antes, o Xterm exigia 4 MB, e agora requer 15 MB apenas para iniciar. O mesmo aumento de consumo é observado no rxvt, que agora requer 16 MB por padrão. O terminal Xfce ocupa 34 MB, o que é três vezes mais do que antes, enquanto o GNOME Terminal exige apenas 20 MB. Claro, todos os testes anteriores foram realizados em uma arquitetura de 32 bits. No LCA 2012, Rasti Russell , existem muitas razões mais sutis que podem explicar o aumento do consumo de memória. Com tudo isso, agora vivemos em tempos em que temos gigabytes inteiros de memória, então conseguiremos lidar com isso de alguma forma.
No entanto, não consigo me livrar da sensação de que alocar uma quantidade maior de memória para um software tão fundamental quanto um terminal é um desperdício de recursos. Esses programas devem ser os menores dos pequenos, capazes de funcionar em qualquer "caixinha", mesmo em uma caixa de sapatos, se algum dia chegarmos ao ponto de que precisarão ser equipados com sistemas Linux (e você sabe que isso vai acontecer). Mas com esses números, o uso de memória se tornará um problema no futuro em qualquer ambiente ao executar vários terminais, exceto em casos de alguns dos mais leves e limitados em recursos. Para compensar isso, o GNOME Terminal, Konsole, urxvt, Terminator e Xfce Terminal possuem um modo Daemon, que permite gerenciar vários terminais através de um único processo, limitando seu consumo de memória.

Durante meus testes, cheguei a outro resultado inesperado sobre a leitura e gravação de disco: esperava não ver nada aqui, mas descobri que alguns terminais gravam os dados mais volumosos no disco. Assim, a biblioteca VTE efetivamente mantém um buffer de rolagem no disco (essa característica , e isso continua até hoje). Mas, ao contrário das implementações antigas, agora, pelo menos, esses dados estão criptografados com AES256 GCM (). Mas surge uma pergunta razoável: o que há de tão especial na biblioteca VTE que exige essa abordagem não convencional à implementação...
Conclusão
Na primeira parte do artigo, descobrimos que os terminais baseados em VTE têm um bom conjunto de recursos, mas agora vemos que isso está relacionado a alguns custos para garantir seu desempenho. Atualmente, a memória não é um problema, pois todos os terminais VTE podem ser gerenciados através de um processo daemon que limita seu uso. No entanto, sistemas mais antigos, com limitações físicas na quantidade de memória RAM e buffer do kernel, podem ainda precisar de versões anteriores dos terminais, já que consomem significativamente menos recursos. Embora os terminais VTE tenham se saído bem em testes de largura de banda (rolagem), sua latência na exibição de dados na tela está acima do limite estabelecido no guia do usuário do GNOME. Provavelmente, os desenvolvedores do VTE deveriam considerar isso. Considerando que, mesmo para usuários iniciantes do Linux, o encontro com o terminal é inevitável, eles podem torná-lo mais amigável ao usuário. Para geeks experientes, a troca do terminal padrão pode significar até uma redução na carga sobre a visão e a possibilidade de evitar lesões e doenças profissionais no futuro devido a longas sessões de trabalho. Infelizmente, apenas os antigos xterm e mlterm nos levam ao mágico limite de latência de 10 milissegundos, o que é inaceitável para muitos.
As medições de controle também mostraram que, devido ao desenvolvimento de ambientes gráficos no Linux, os desenvolvedores tiveram que fazer uma série de concessões. Alguns usuários devem considerar gerenciadores de janelas comuns, pois eles proporcionam uma redução significativa no ping. Infelizmente, para o Wayland, não consegui medir a latência: o programa Typometer, que usei, foi criado para evitar exatamente o que o Wayland se propõe a prevenir — a espionagem de outras janelas. Espero que a composição no Wayland tenha um desempenho melhor do que o X.org, e também espero que, no futuro, alguém encontre uma maneira de avaliar o nível de latência nesse ambiente.
Fonte: habr.com
