Vamos ainda mais enfatizar que xxd -p
é irrelevante, estamos não falando sobre a saída its . Ele nem viu a entrada devido ao buffer de linha no lado do kernel e, portanto, não produziu nenhuma saída. Por que vale a pena, também pode ser um cat
ou um sleep 100000
ou o que for. Estamos falando sobre como o kernel (a disciplina de linha) ecoa de volta a entrada.
Se você voltar para UTF-8 e pressionar Enter para xxd -p
, sua saída será igual a fffe6100fffe6100
. Então little endian é confirmado (ou provavelmente é a ordem de bytes nativa da arquitetura), mas, surpreendentemente, há uma BOM antes de cada caractere. Faz-me suspeitar que não foi devidamente pensado pelos desenvolvedores do Konsole, eles apenas invocam cegamente o iconv com UTF-16 (sem BE ou LE especificado) como o conjunto de caracteres de destino, para cada pedaço de entrada à medida que se torna disponível e iconv places lá.
Vamos strace
konsole para ver o que ele faz no descritor de arquivo conectado a /dev/ptmx
:
write(..., "76awrite(..., "76a%pre%", 4) = 4
[...]
read(..., "76a^@", 5) = 5
", 4) = 4
[...]
read(..., "76a^@", 5) = 5
O byte NUL (0x00) retorna como literal ^@
, ou seja, 0x5e seguido por 0x40.
Juntamente com a
(0x61), isso dá a você U + 5e61, que é exatamente o primeiro glifo que você vê aparecendo. Além disso, você estará desligado por um byte, ou seja, o próximo byte supostamente baixo será interpretado como alto byte e vice-versa.
Para o byte 0x00
, o kernel simplesmente manipula como é ecoado de volta. Para alguns outros bytes, também executa outras ações. Por exemplo, o byte 0x03
( ^C
) geralmente aciona uma interrupção para ser enviada ao processo em primeiro plano, 0x15
( ^U
) apaga os dados que você inseriu até o momento, 0x0a
e / ou 0x0d
(isto é, nova linha) libera os dados para seu aplicativo, etc. Todos esses bytes podem (e realmente) ocorrem legalmente dentro da representação de caracteres UTF-16, e você certamente não quer que nenhum deles aconteça enquanto digita sua entrada .
Para usar o UTF-16 na linha discipular, o kernel precisaria fornecer suporte explícito para isso e precisaria ser informado de que esta codificação está sendo usada (algo nos moldes de um stty utf16
). Para o meu melhor conhecimento, isso não é implementado (felizmente - seria um desperdício total de recursos do desenvolvedor). O kernel espera que uma codificação compatível com ASCII seja usada, o que não é o UTF-16.
Mesmo se o UTF-16 fosse implementado no kernel para a linha tty, todo o ecossistema seria necessariamente bastante frágil. O terminal pode receber dados de várias fontes simultaneamente, e não há como garantir que todos os produtores de dados e todos os transportadores (por exemplo, ssh) possam sempre manter os bytes acoplados em pares. Uma vez que se apaga um byte (como visto acima), o resto é inutilizável.
Agora estou mais certo de que o desenvolvedor do Konsole não pensou corretamente sobre isso. Na minha opinião, o UTF-16 deve ser removido de sua lista de codificações oferecidas, ou pelo menos uma advertência deve ser mostrada. Eu enviei o erro do Konsole 395171 .