Caracteres não-ascii não são mais exibidos no bash

2

Atualizado: Este não é um problema no sistema de arquivos.

Eu costumava entrar:

$ echo kødpålæg

Mas agora o bash / zsh muda isso para:

bash$ echo kddddddddplg
zsh$ echo k<c3><b8>dp<c3><a5>l<c3><a6>g

Eu posso executar cat e digitar 'kødpålæg' sem problemas:

$ cat
kødpålæg
kødpålæg

Isso é com esse ambiente:

$ locale   
LANG=C
LANGUAGE=C
LC_CTYPE="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_PAPER="C"
LC_NAME="C"
LC_ADDRESS="C"
LC_TELEPHONE="C"
LC_MEASUREMENT="C"
LC_IDENTIFICATION="C"
LC_ALL=C

e nisso:

$ locale 
LANG=da_DK.utf8
LANGUAGE=da_DK.utf8
LC_CTYPE="da_DK.utf8"
LC_NUMERIC="da_DK.utf8"
LC_TIME="da_DK.utf8"
LC_COLLATE="da_DK.utf8"
LC_MONETARY="da_DK.utf8"
LC_MESSAGES="da_DK.utf8"
LC_PAPER="da_DK.utf8"
LC_NAME="da_DK.utf8"
LC_ADDRESS="da_DK.utf8"
LC_TELEPHONE="da_DK.utf8"
LC_MEASUREMENT="da_DK.utf8"
LC_IDENTIFICATION="da_DK.utf8"
LC_ALL=da_DK.utf8

csh não altera 'kødpålæg'.

Como posso recuperar o antigo comportamento para poder inserir 'kødpålæg'?

A execução de qualquer um deles fornece o comportamento antigo:

LC_ALL=en_GB.utf-8 luit
LC_ALL=da_DK.utf-8 luit
LC_ALL=en_GB.iso88591 luit
LC_ALL=da_DK.iso88591 luit

mas apenas para essa única sessão.

Isto:

$ od -An -vtx1
ø

Dá:

 c3 b8 0a

Portanto, parece que a entrada do Konsole para bash é UTF8.

$ konsole --version
QCoreApplication::arguments: Please instantiate the QApplication object first
Qt: 5.5.1
KDE Frameworks: 5.18.0
Konsole: 15.12.3

$ bash --version
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

$ zsh --version
zsh 5.1.1 (x86_64-ubuntu-linux-gnu)

$ dpkg -l csh
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name              Version       Architecture  Description
+++-=================-=============-=============-========================================
ii  csh               20110502-2.1u amd64         Shell with C-like syntax
    
por Ole Tange 10.06.2018 / 23:36

2 respostas

3

Eu diria que seu terminal está mal configurado e envia e exibe caracteres em algum conjunto de caracteres de byte único, provavelmente ISO8859-1 ou ISO8859-15, dados os caracteres de amostra mostrados em vez do conjunto de caracteres do locale.

Geralmente, não há caracteres ø , å , æ na localidade C e a codificação ISO8859-1 (5) desses caracteres (0xf8, 0xe5, 0xe6) não formam caracteres válidos em UTF -8. Editores de linha como readline ou zle precisam decodificá-los em caracteres, pois precisam saber quantos bytes formam uma coluna de exibição para que possam posicionar corretamente o cursor.

Além disso, no local C, que na maioria dos sistemas usa ASCII, já que não há caracteres em ASCII com o conjunto de bits 8 th , esse bit 8 th seria entendido por bash como significando Meta . 0xF8 seria entendido como significando Meta + x (0x78 (x) | 0x80), porque é isso que alguns terminais enviam em Alt + x ou Meta + x .

Enquanto M-x não está vinculado a nada por padrão em bash , ß seria entendido como M-_ e inserir a última palavra. Você pode desativar isso com:

bind 'set convert-meta off'

Shells como csh são antigos demais para estarem cientes de que os caracteres podem ser feitos de vários bytes ou ocupam qualquer coisa além de uma única largura de coluna, então eles não se incomodam.

Para verificar essa teoria, execute:

od -An -vtx1

Digite esses caracteres seguidos por ^D^D e veja qual codificação você vê. Se você ver 0xf8 para ø , isso significa que estou certo. Se você vir 0xc3 0xb8, que é a codificação UTF-8 de ø , isso significa que estou errado.

Ou altere a localidade para da_DK.iso88591 (verifique em locale -a o nome exato da localidade em seu sistema) e veja se isso funciona melhor.

Agora, por que seu terminal pode enviar a codificação incorreta para esses caracteres, talvez tenha sido iniciado em uma localidade onde o conjunto de caracteres era iso8859-1. Talvez esteja configurado para ignorar a localidade e usar um conjunto de caracteres específico (procure charset ou codificação em sua configuração). Ou talvez você tenha ssh ed de outro sistema onde o local estava usando ISO8859-1 (5) como charset.

Eu posso reproduzir esse comportamento se de um terminal UTF-8, eu corro:

LC_ALL=en_GB.iso885915 luit

E de luit altere a localidade para C ou uma UTF-8 e insira caracteres não-ASCII.

    
por 11.06.2018 / 10:29
0

Seu teste cat indica que a conexão do terminal é de 8 bits limpa. Então parece um possível problema local.

Por favor, execute locale -a para verificar se a sua localidade escolhida "da_DK.utf8" existe; se não estiver listado, e você estiver em um sistema que pertence à família Debian / Ubuntu, você pode ter que descomentar em /etc/locale.gen e então executar locale-gen como root.

Além disso, algumas versões do shell não podem mudar de localidade dinamicamente, mas continuam usando a configuração de locale que foi originalmente herdada de seu processo pai . Se esse for o caso, a execução de LC_CTYPE=da_DK.UTF-8 bash restauraria o comportamento desejado, somente para o período daquela sessão específica. Se isso for verdade, alterar o código de idioma padrão do sistema para qualquer código de idioma UTF-8 suportado e, em seguida, reinicializar pode ajudar: ele alteraria o código de idioma dos processos responsáveis por manipular seu login e iniciar seu shell.

    
por 11.06.2018 / 10:07