Efeito de $ LANG no terminal

11

Estou tentando aprender como a $LANGvariável se comporta com o gnome-terminal (e sua opção de preferência de codificação de caracteres). Eu tenho usado iso8859-1 (latin1) como meu conjunto de caracteres principal e todos os meus nomes de arquivo são codificados como tal.

Para os testes a seguir, criarei ls -lum diretório com caracteres acentuados em espanhol nos nomes de arquivos:

Caso 1:

  • terminal gnome configurado para ISO-8859-1
  • LANG definido como "en_US-iso8859-1"
  • Resultado: vejo todos os arquivos corretamente

Caso 2:

  • terminal gnome configurado para UTF-8
  • LANG definido como "en_US-iso8859-1"
  • Resultado: vejo caracteres ilegíveis para todos os caracteres em espanhol. Isso é esperado quando eu mudei a codificação de caracteres para o terminal

Caso 3:

  • terminal gnome configurado para ISO-8859-1
  • LANG definido como "en_US-UTF-8"
  • Resultado: vejo caracteres ilegíveis para todos os caracteres em espanhol.

Por que, neste último caso, vejo caracteres ilegíveis? A saída de ls não deve enviar os nomes de arquivos diretamente para o terminal gnome como estão? E como o gnome-terminal está configurado para ISO-8859-1, eu esperava que eles parecessem corretos.

Por um momento, pensei que, talvez, talvez o bash esteja considerando minha $LANGvariável e realizando alguma conversão. Então mudei meu terminal para UTF-8, mas ainda não consigo ver os caracteres corretamente. Até canalizei a saída de ls para xxd e, para minha surpresa, ainda vejo os arquivos codificados como estão: ISO-8859-1.

Para finalizar: Se minha listagem contiver caracteres ISO-8859-1 e meu emulador de terminal estiver configurado para a mesma codificação de caracteres: Quem está fazendo a conversão quando LANGestá definido de outra forma?

Obrigado por qualquer ajuda que você pode fornecer.

Craconia

Craconia
fonte

Respostas:

5

Sua configuração LANGdeve corresponder à do terminal. Mais precisamente, sua configuração para LC_CTYPE(a codificação de caracteres) deve corresponder à codificação do terminal, as outras configurações de localidade não precisam corresponder. E a codificação do terminal geralmente é especificada por uma opção do emulador de terminal e não por uma variável de localidade. Ele LC_CTYPEcombina duas indicações: informa aos aplicativos qual codificação usar no terminal (para entrada e saída) e informa aos aplicativos que codificação usar nos arquivos. Nos casos 2 e 3, você pediu lspara exibir a saída em uma codificação diferente da do terminal, para que a saída seja ilegível.

Se você trabalha com as codificações UTF-8 e latin-1 em momentos diferentes, configure seu terminal para usar UTF-8. Isso deve fazer com que seja definido LC_CTYPEcomo um valor indicando UTF-8; não substitua essa configuração. (Se o emulador de terminal não estiver configurado LC_CTYPE, substitua-o no arquivo de inicialização do shell ou em toda a sessão.) Para trabalhar com dados latin-1 em um terminal UTF-8, use luit(incluído no pacote de utilitários X).

LC_CTYPE=en_US.iso88591 luit

(Você pode usar qualquer outro local com a mesma codificação, por exemplo LC_CTYPE=es_ES.iso88591 luit.)

Gilles 'SO- parar de ser mau'
fonte
Obrigado Gilles pela maravilhosa explicação, especialmente por explicar as duas indicações para LC_CTYPE.
Craconia 21/09/12
Voltando ao meu último caso: eu pensei que, como todos os nomes de arquivos eram codificados em latin1 mais o fato de que meu dispositivo de saída final, aquele que criava os glifos (meu terminal), também estava configurado para latin1, eu esperava ver os arquivos corretamente (independentemente de LC_CTYPE) ...
Craconia
Nunca me ocorreu que lsconsideraria LC_CTYPE (definido como UTF-8 neste caso) e executaria algum tipo de validação de conjunto de caracteres: sempre que vir algo incompatível com o conjunto de caracteres, cuspiria um caractere específico (por exemplo, "? "). Eu disse "validação" porque não executará uma "conversão" como o luit faz. É assim?
Craconia 21/09/12
@Craconia No terceiro caso, lssubstitui os caracteres não imprimíveis por ?. A maioria das strings codificadas em latin-1 que representam palavras reais têm caracteres não imprimíveis se interpretadas como UTF-8.
Gilles 'SO- stop be evil'
5

Nos casos 2 e 3, você mistura duas codificações UTF-8 e Latin-1 diferentes. No caso 1, você está usando o Latin-1 para ambos, para não ter problemas.

O lscomando (e todos os outros programas com bom comportamento) usam a configuração LANG para determinar a codificação .

Você pode misturar dois idiomas diferentes, mas não deve misturar duas codificações diferentes .

Certifique-se de que as variáveis ​​de ambiente LC_ * também usem a mesma codificação que sua variável LANG.

Como regra geral, você deve configurar seu sistema hoje em dia para usar apenas UTF-8.

Se você precisar editar arquivos de dados antiquados (por exemplo, propriedades java), use um editor especializado (por exemplo, java ide) ou garanta a codificação com ferramentas como iconvou `recode ..

H.-Dirk Schmitt
fonte
Obrigado. Sim, tenho planos de mudar para UTF-8 em um futuro próximo. Temos vários nomes de arquivos para converter, além de muitos arquivos de texto. iconv e convmv para o resgate ...
Craconia
0

Isso pode estar fora de sua necessidade, mas ....

Acontece que no RHEL5, e provavelmente antes, muitas das páginas de manual, de alguma forma, por algum motivo esquecido por D'us, foram identificadas. Ou seja, a página de manual bruta foi convertida de seu conjunto de caracteres nativo para ASCII de 7 bits. Não importa o que você faça com LC e LANG, a página de manual latin1produz uma página de manual que é efetivamente inútil. Todos os caracteres especiais (8 bits) foram substituídos por espaços reservados de 7 bits (geralmente ??). Eu acho isso hilário.

Mas a utf8versão dessas páginas de manual pode existir no diretório específico do idioma. O truque é pedir pelo nome correto. Por exemplo, latin1 é realmente iso_8859-1. Se você criar uma página de manual e suas configurações LANG estiverem corretas, você verá o que espera; a página de manual é encontrada no subdir ( en/man7/iso_8859-1.7) específico do idioma . Mas se você solicitar iso-8859-1, por algum motivo, você obtém a versão ASCII.

Otheus
fonte