Quando você pressiona Ctrl+X, o emulador de terminal grava o byte 0x18 no lado principal do par pseudo-terminal.
O que acontece a seguir depende de como a disciplina tty line (um módulo de software no kernel que fica entre o lado mestre (sob controle do emulador) e o lado escravo (com o qual os aplicativos em execução no terminal interagem)) está configurada.
Um comando para configurar essa disciplina de linha tty é o sttycomando.
Ao executar um aplicativo idiota como catesse não está ciente e não se importa se seu stdin é um terminal ou não, o terminal está no modo canônico padrão , onde a disciplina de linha tty implementa um editor de linha bruta .
Alguns aplicativos interativos que precisam mais do que o editor de linha bruta geralmente alteram essas configurações na inicialização e as restauram ao sair. As conchas modernas, quando solicitadas, são exemplos dessas aplicações. Eles implementam seu próprio editor de linha mais avançado.
Normalmente, enquanto você digita uma linha de comando, o shell coloca a disciplina da linha tty nesse modo e, quando você pressiona enter para executar o comando atual, o shell restaura o modo tty normal (como estava em vigor antes de emitir o prompt).
Se você executar o stty -acomando, verá as configurações atuais em uso para os aplicativos mudos . É provável que você ver a icanon, echoe echoctldefinições a ser habilitado.
O que isso significa é que:
icanon: esse editor de linha bruta está ativado.
echo: os caracteres digitados (que o emulador de terminal grava no lado mestre) são repetidos (disponibilizados para leitura pelo emulador de terminal).
echoctl: em vez de serem repetidos como asis, os caracteres de controle são repetidos como ^X.
Então, digamos que você digite A B Backspace-aka-Ctrl+H/? C Ctrl+X Backspace Return.
Seu emulador de terminal irá enviar: AB\bC\x18\b\r. A disciplina de linha ecoará de volta :,AB\b \bC^X\b \b\b \b\r\n e um aplicativo que lê a entrada do lado escravo ( /dev/pts/x) lerá AC\n.
Tudo o que o aplicativo vê é AC\n, e somente quando você pressiona, Enterpara que ele não possa ter nenhum controle na saída por ^Xlá.
Você notará que, para eco , o primeiro ^H( ^?com alguns terminais, consulte a eraseconfiguração) resultou no \b \benvio de volta ao terminal. Essa é a sequência para mover o cursor para trás, substituir o espaço, mover o cursor para trás novamente, enquanto o segundo ^Hresultou na \b \b\b \bexclusão desses dois ^e Xcaracteres.
O próprio ^X(0x18) estava sendo traduzido para ^e Xpara saída. Como B, não chegou ao aplicativo, pois o excluímos com Backspace.
\r(aka ^M) foi traduzido para \r\n( ^M^J) para eco e \n( ^J) para o aplicativo.
Então, quais são as nossas opções para essas aplicações idiotas :
- desativar
echo( stty -echo). Isso muda efetivamente a maneira como os caracteres de controle são repetidos, ... não repetindo nada. Não é realmente uma solução.
- desativar
echoctl. Isso muda os caracteres de controle caminho (exceto ^H, ^M... e todos os outros utilizados pelo editor de linha) são ecoados. Eles são ecoados como estão. Por exemplo, o caractere ESC é enviado como o byte \e( ^[/ 0x1b) (que é reconhecido como o início de uma sequência de escape pelo terminal), ^Gvocê envia um \a(um BEL, emitindo um bipe no terminal) ... Não é uma opção .
- desative o editor de linha bruta (
stty -icanon). Não é realmente uma opção, pois os aplicativos brutos se tornariam muito menos utilizáveis.
- edite o código do kernel para alterar o comportamento da disciplina de linha tty, para que o eco de um caractere de controle seja enviado em
\e[7m^X\e[mvez de apenas ^X(aqui \e[7mgeralmente habilita o vídeo reverso na maioria dos terminais).
Uma opção poderia ser usar um invólucro como rlwrapesse, um hack sujo para adicionar um editor de linhas sofisticado a aplicativos burros. Com efeito, esse invólucro tenta substituir read()s simples do dispositivo terminal por chamadas para o editor de linha readline (que alteram o modo da disciplina de linha tty).
Indo ainda mais longe, você pode tentar soluções como esta, que sequestram toda a entrada do terminal para passar pelo editor de linha do zsh (que por acaso destaca ^Xs no vídeo reverso), contando com o :execrecurso da tela GNU .
Agora, para aplicativos que implementam seu próprio editor de linha, cabe a eles decidir como o eco é feito. bashusa readline para aquilo que não tem suporte para personalizar como os caracteres de controle são repetidos.
Para zsh, veja:
info --index-search='highlighting, special characters' zsh
zshdestaca caracteres não imprimíveis por padrão. Você pode personalizar o destaque com, por exemplo:
zle_highlight=(special:fg=white,bg=red)
Para branco e vermelho, destaque para esses caracteres especiais.
A representação de texto desses caracteres não é personalizável.
Em um locale UTF-8, 0x18 será processado como ^X, \u378, \U7fffffff(dois pontos de código unicode não atribuídos), como <0378>, <7FFFFFFF>, \u200b(um caractere Unicode não-realmente impressa) como <200B>.
\x80em um código de idioma iso8859-1 seria renderizado como ^�... etc.
bashele éreadlinelidar com essas coisas, e para a maioria dos outros é o driver tty.