SSD Nodes Learn 🎉 VPS desde $5.50/mês
Guias Matt ConnorPor Matt Connor

Como corrigir "unknown terminal type" no SSH

Veja por que o erro "unknown terminal type" ocorre no SSH e instale uma entrada terminfo em ~/.terminfo, sem root e sem alterar o sistema.

O que significa "unknown terminal type"

Um erro de tipo de terminal desconhecido através de SSH significa que o nome em TERM não tem uma entrada correspondente na base de dados terminfo no servidor. O seu emulador define esse nome no seu computador portátil. A base de dados que tem de o reconhecer está na máquina remota. Quando a pesquisa falha, todos os programas curses nesse servidor terminam antes de apresentar qualquer conteúdo, porque não têm uma descrição das capacidades do seu terminal.

A correção que preserva todas as funcionalidades do seu emulador consiste num comando: compilar a sua própria entrada terminfo em ~/.terminfo no servidor. O ncurses pesquisa o seu diretório pessoal antes de qualquer diretório do sistema. Por isso, não é necessário ter root e nada é alterado para os outros utilizadores.

TERM é um nome, terminfo é a base de dados

TERM contém uma cadeia de caracteres, e essa cadeia é apenas uma chave. terminfo é uma base de dados compilada com descrições de terminais, e a chave é usada por um programa para encontrar a descrição correta. Uma descrição regista quantas cores o terminal suporta, quais bytes movem o cursor para a linha 12, coluna 40, quais bytes a tecla F5 envia e se o terminal consegue desenhar um sublinhado com estilo. ncurses, a biblioteca em que quase todas as interfaces de utilizador de texto no Linux são baseadas, lê essa descrição no arranque. Programas como top, less, nano e watch não conseguem desenhar um único ecrã sem ela.

Consulte a sua própria entrada:

echo "$TERM"
tput longname
infocmp -1 | head -20

tput longname imprime a descrição legível por humanos daquilo que TERM identifica. Para xterm-256color, imprime:

xterm with 256 colors

infocmp -1 descompila a entrada completa e imprime uma capacidade por linha. Se ambos os comandos funcionarem, a base de dados desta máquina conhece este terminal. Esse é também o estado necessário do outro lado de uma ligação SSH.

Por que isso falha apenas por SSH

O SSH envia o nome e nada mais. Quando o cliente solicita um pseudo terminal, TERM segue com essa solicitação. O manual do OpenSSH é explícito: "a variável de ambiente TERM é sempre enviada quando um pseudo terminal é solicitado, pois é necessária para o protocolo". Assim, o seu shell de login na VPS recebe TERM=xterm-ghostty, xterm-kitty ou qualquer outro nome usado pelo seu emulador. A descrição associada a esse nome permanece no seu laptop, na base de dados do seu laptop. Um servidor criado antes de o seu emulador existir nunca ouviu esse nome. Nada em a própria ligação SSH copia as descrições de terminal, e isso é intencional: o protocolo transporta um nome, não uma lista de capacidades.

Reproduza a falha na sua própria máquina com um nome que certamente não existe:

TERM=xterm-nosuchthing tput colors
echo "$?"
tput: unknown terminal "xterm-nosuchthing"

O status de saída é 3, que o ncurses documenta como um tipo de terminal desconhecido ou uma base de dados ausente. Todos os programas curses fazem a mesma consulta, portanto um único nome ausente produz uma mensagem diferente em cada programa, mas com a mesma causa. nano termina com Error opening terminal: xterm-nosuchthing., a falha padrão do ncurses quando não consegue carregar uma descrição na inicialização. vim imprime E558: Terminal entry not found in terminfo. less imprime WARNING: terminal is not fully functional. Um pager que funciona parcialmente e um editor que se recusa a iniciar parecem problemas sem relação. São o mesmo ficheiro ausente.

Onde o ncurses procura a entrada

O ncurses pesquisa numa ordem fixa, documentada em terminfo(5):

  1. $TERMINFO, se estiver definida. Apenas esse diretório é pesquisado.
  2. $HOME/.terminfo.
  3. Todos os diretórios listados em $TERMINFO_DIRS.
  4. As localizações incorporadas na compilação, que no Debian e no Ubuntu incluem /etc/terminfo, /lib/terminfo e /usr/share/terminfo.

Execute infocmp -D no servidor para apresentar a lista usada pela própria compilação do ncurses, em vez de confiar nos caminhos acima. O passo 2 é o ponto essencial. O seu diretório pessoal é pesquisado antes de qualquer diretório do sistema. Por isso, um ficheiro em ~/.terminfo corrige a pesquisa para a sua conta, sem instalar pacotes e sem root.

Correção 1: use um TERM que o servidor já conheça

A forma mais rápida de desbloquear a situação é indicar um terminal diferente para uma ligação:

TERM=xterm-256color ssh user@203.0.113.10

Torne essa configuração permanente para esse host em ~/.ssh/config no seu portátil:

Host vps1
    HostName 203.0.113.10
    User deploy
    SetEnv TERM=xterm-256color

SetEnv requer o OpenSSH 7.8 ou mais recente no cliente, lançado em agosto de 2018. TERM é a única variável que não requer autorização do servidor: o manual diz que "Tal como acontece com SendEnv, com exceção da variável TERM, o servidor tem de estar preparado para aceitar a variável de ambiente". Por isso, isto funciona mesmo contra um sshd reforçado sem qualquer linha AcceptEnv.

Custo: tudo o que o seu emulador descreve para além de xterm-256color simples. Isso inclui a cor de 24 bits anunciada através da capacidade RGB e os sublinhados estilizados através de Smulx. Os programas deixam de conseguir ver essas capacidades e passam a usar 256 cores e um sublinhado simples. O ecrã funciona. Apenas fica menos capaz do que o terminal que escolheu.

Não resolva isto adicionando export TERM=xterm-256color ao seu .bashrc no servidor. Esse ficheiro é executado para todas as ligações, incluindo as ligações de um terminal cujo nome o servidor conheça, e por isso reduz as capacidades de sessões que já funcionavam corretamente. Mantenha a substituição no cliente, onde sabe qual é o emulador que está a executar.

Correção 2: envie a sua entrada terminfo para o servidor uma vez

Esta é a correção que mantém o seu emulador intacto. Descompile a entrada localmente, envie-a através do SSH e compile-a no servidor:

infocmp -x | ssh user@203.0.113.10 -- tic -x -

infocmp -x imprime a entrada do seu TERM atual como texto-fonte, incluindo capacidades estendidas (definidas pelo utilizador). tic -x compila esse texto-fonte novamente numa descrição binária no servidor. O -x em ambos os lados é importante, porque, sem ele, capacidades como Smulx são descartadas durante a transferência e é enviada uma cópia degradada do seu próprio terminal.

tic escreve no diretório do sistema quando tem permissão para isso e recorre a $HOME/.terminfo quando o utilizador não tem acesso de escrita nesse diretório. Uma conta normal numa VPS utiliza o diretório pessoal, que é o comportamento pretendido. Também pode indicar o destino:

infocmp -x | ssh user@203.0.113.10 -- tic -x -o '~/.terminfo' /dev/stdin

As aspas à volta de ~/.terminfo não são decorativas. ssh junta as palavras do comando numa única cadeia e entrega-a ao shell remoto, por isso um ~ sem aspas é expandido primeiro pelo seu shell local. Em seguida, envia um /home/yourname/.terminfo literal para uma máquina onde a sua conta pode ter outro nome. tic falha com um erro de permissão ou escreve num caminho que o ncurses nunca pesquisa. Coloque as aspas à volta do til e deixe o shell remoto expandi-lo.

Inicie sessão e verifique:

ssh user@203.0.113.10
tput longname
ls -R ~/.terminfo

tput longname imprimir a descrição do seu terminal significa que a pesquisa foi bem-sucedida, e ls mostra o ficheiro compilado dentro de um subdiretório cujo nome corresponde à primeira letra do nome do terminal. Em seguida, execute top ou watch -n1 uptime, que redesenha o ecrã através da mesma biblioteca, para confirmar que um programa curses real consegue desenhar o ecrã.

O custo é um passo por servidor, e a entrada fica no diretório pessoal de uma conta numa única máquina. Se reconstruir a VPS, a entrada desaparece. Inclua o comando na ferramenta que utiliza para provisionar e gerir vários servidores em simultâneo, para que um novo host já tenha a entrada compilada.

Corrigir 3: instalar a base de dados terminfo expandida

Se tiver root e quiser que o nome seja resolvido para todas as contas do servidor:

sudo apt update
sudo apt install ncurses-term
tput -T xterm-ghostty longname

ncurses-term contém as descrições de terminais que a instalação base não inclui. Corrige o nome para root e para todos os outros utilizadores, ao contrário da correção 2.

Só ajuda quando a entrada do seu terminal existe na versão do ncurses que a sua distribuição empacotou. Por isso, verifique em vez de presumir. O Ubuntu 24.04 inclui ncurses-bin 6.4+20240113-1ubuntu2.1 (em agosto de 2026). A entrada do Ghostty foi adicionada no ncurses upstream 6.5-20241228, que é mais recente. Por isso, apt install ncurses-term no Ubuntu 24.04 não pode gerar uma entrada xterm-ghostty, independentemente do número de vezes que o executar. tput -T <name> longname faz a verificação: imprime a descrição quando a entrada existe e unknown terminal com o código de saída 3 quando ela não existe.

Para instalar uma única entrada em todo o sistema, em vez do pacote completo, copie o código-fonte e compile-o como root:

infocmp -x | ssh user@203.0.113.10 -- 'cat > /tmp/term.src'
ssh -t user@203.0.113.10 -- sudo tic -x -o /usr/share/terminfo /tmp/term.src

O -t no segundo comando aloca um terminal pseudo-TTY, para que sudo possa pedir a palavra-passe. Sem ele, sudo pode terminar com sudo: no tty present and no askpass program specified.

Deixe o emulador fazer a transferência

Alguns emuladores incluem um auxiliar que aplica a correção 2 automaticamente. O kitty tem um ssh kitten: kitten ssh myserver liga-se ao host remoto e copia automaticamente o terminfo do kitty. A documentação também apresenta a forma manual, infocmp -a xterm-kitty | ssh myserver tic -x -o \~/.terminfo /dev/stdin, com o til escapado pelo motivo descrito acima. O Ghostty documenta infocmp -x xterm-ghostty | ssh YOUR-SERVER -- tic -x - e inclui integração com a shell (ssh-env e ssh-terminfo), além de uma ação +ssh que automatiza ambas as correções.

Estes auxiliares executam os mesmos comandos que acabou de executar manualmente. Ainda é importante conhecer a forma manual, porque o auxiliar não pode atuar quando a ligação é iniciada noutro local, num jump host ou dentro de um script.

Quando o erro volta

Em sudo -i. Uma shell de login como root tem HOME=/root, e sudo mantém o seu TERM. O ncurses procura agora em /root/.terminfo, que não contém a sua entrada, por isso a falha volta a ocorrer apenas para root. Confirme com sudo -i env e leia as linhas HOME e TERM. Instale a entrada no diretório do sistema ou coloque uma cópia em /root/.terminfo.

Dentro de tmux ou screen. Estes programas definem o seu próprio TERM para os programas executados dentro deles, normalmente screen-256color ou tmux-256color. Um servidor mais antigo conhece screen-256color e pode não conhecer tmux-256color, por isso a shell exterior funciona, enquanto tudo dentro da sessão falha. A causa é a mesma, mas o nome é diferente. Execute tput -T tmux-256color longname no servidor para verificar qual dos dois ele possui. Um ambiente de trabalho de terminal baseado em tmux oculta este problema até ao dia em que se liga a um host que ainda não corrigiu.

Num servidor novo. ~/.terminfo é específico de cada conta e máquina, por isso um VPS reinstalado volta a ficar vazio.

O ecrã é apresentado, mas as teclas comportam-se mal. Se o ecrã estiver correto, mas Home, End ou as teclas de função inserirem caracteres inesperados, o nome foi resolvido para uma entrada que não corresponde ao seu terminal. As sequências de teclas vêm da mesma entrada terminfo que define as capacidades de apresentação, por isso uma entrada aproximada produz teclas aproximadas. Esse é o resultado habitual da correção 1 num emulador cujas sequências de teclas diferem de xterm. A correção 2 resolve o problema, porque apenas a entrada real do seu emulador contém as sequências corretas.

FAQ

Por que só vejo "unknown terminal type" através de SSH?

Porque a base de dados que tem de conter a entrada do seu terminal é a do servidor. O seu emulador instala a descrição na máquina onde é executado, por isso os programas locais encontram-na sem qualquer intervenção sua. O SSH envia apenas o valor de TERM, porque o protocolo transporta esse nome no pedido de pseudo-terminal. O ncurses remoto procura o nome na base de dados remota e não encontra nada, por isso initscr falha e o programa termina.

Posso corrigir isto sem root no servidor?

Sim. O ncurses procura $HOME/.terminfo antes de qualquer diretório do sistema, por isso uma entrada nesse local é suficiente para a sua conta. Execute infocmp -x | ssh user@host -- tic -x - uma vez por servidor. tic escreve no seu diretório pessoal quando não consegue escrever no caminho do sistema, que é o caso normal para uma conta sem privilégios. Inicie sessão e execute tput longname para confirmar que a pesquisa já é resolvida.

O que perco ao definir TERM=xterm-256color para um host?

Todas as capacidades descritas pelo seu emulador além da entrada xterm-256color, como cor de 24 bits através de RGB e sublinhados estilizados através de Smulx. Os programas não conseguem ver essas capacidades, por isso usam a alternativa mais próxima. As sequências das teclas de função também podem ser diferentes das do seu terminal real. Coloque a definição no cliente, em ~/.ssh/config, e não num .bashrc no servidor, porque isso degradaria as sessões de terminais que já funcionavam.

Por que o erro volta depois de sudo -i?

sudo -i inicia uma shell de login como root com HOME=/root, mantendo o seu valor de TERM. O ncurses procura então /root/.terminfo em vez do seu próprio diretório pessoal e não encontra nada, por isso root vê a mesma falha que já não afeta a sua conta. Execute sudo -i env e verifique as linhas HOME e TERM. Compile a entrada no diretório do sistema com sudo tic -x -o /usr/share/terminfo ou copie-a para /root/.terminfo.

apt install ncurses-term corrige sempre o problema?

Não. Apenas adiciona as entradas que existiam na versão do ncurses incluída pela sua distribuição. Ubuntu 24.04 disponibiliza ncurses 6.4 (ncurses-bin 6.4+20240113-1ubuntu2.1, em agosto de 2026), e a entrada do Ghostty foi adicionada upstream no ncurses 6.5-20241228, por isso esse pacote não a pode conter. Verifique com tput -T <name> longname antes de depender do pacote e disponibilize a entrada manualmente quando a verificação continuar a indicar um terminal desconhecido.

#terminfo#ssh#ncurses#tput#terminal