Efecto de $ LANG en la terminal

11

Estoy tratando de aprender cómo se $LANGcomporta la variable con gnome-terminal (y su opción de preferencia de codificación de caracteres). He estado usando iso8859-1 (latin1) como mi conjunto de caracteres principal y todos mis nombres de archivo están codificados como tales.

Para las siguientes pruebas, haré ls -lun directorio con caracteres acentuados en español en sus nombres de archivo:

Caso 1:

  • terminal gnome configurado para ISO-8859-1
  • LANG establecido en "en_US-iso8859-1"
  • Resultado: veo todos los archivos correctamente

Caso # 2:

  • terminal gnome configurado para UTF-8
  • LANG establecido en "en_US-iso8859-1"
  • Resultado: veo caracteres basura para todos los caracteres españoles. Esto se espera cuando cambié la codificación de caracteres para el terminal

Caso # 3:

  • terminal gnome configurado para ISO-8859-1
  • LANG establecido en "en_US-UTF-8"
  • Resultado: veo caracteres basura para todos los caracteres españoles.

¿Por qué es que en este último caso veo personajes confusos? ¿No debería la salida de ls enviar los nombres de archivo directamente a gnome-terminal tal como están? Y dado que gnome-terminal está configurado para ISO-8859-1, hubiera esperado que se vean bien.

Por un momento pensé que, tal vez, tal vez bash esté considerando mi $LANGvariable y realizando alguna conversión. Luego cambié mi terminal a UTF-8 pero todavía no puedo ver los caracteres correctamente. Incluso canalicé la salida de ls a xxd y para mi sorpresa, todavía veo los archivos codificados como están: ISO-8859-1.

Para concluir: si mi listado contiene caracteres ISO-8859-1 y mi emulador de terminal está configurado para la misma codificación de caracteres: ¿Quién está haciendo la conversión cuando LANGse establece lo contrario?

Gracias por cualquier ayuda que usted nos pueda proporcionar.

Craconia

Craconia
fuente

Respuestas:

5

Su configuración LANGdebe coincidir con la del terminal. Más precisamente, su configuración para LC_CTYPE(la codificación de caracteres) debe coincidir con la codificación del terminal, las otras configuraciones locales no necesitan coincidir. Y la codificación del terminal generalmente se especifica mediante una opción del emulador de terminal y no mediante una variable de configuración regional. Las LC_CTYPEcosechadoras dos indicaciones: se dice lo que las aplicaciones que codifican para el uso en el terminal (tanto para la entrada y salida), y se le dice lo que las aplicaciones que codifican para usar con los archivos. En los casos 2 y 3, le ha dicho lsque muestre la salida en una codificación que sea diferente de la del terminal, por lo que la salida es confusa.

Si trabaja con codificaciones UTF-8 y latin-1 en diferentes momentos, configure su terminal para usar UTF-8. Esto debería provocar que se establezca LC_CTYPEen un valor que indique UTF-8; No anule esta configuración. (Si el emulador de terminal no se configura LC_CTYPE, anúlelo en su archivo de inicio de shell o para toda su sesión). Para trabajar con datos latin-1 en un terminal UTF-8, use luit(incluido en el paquete de utilidades X).

LC_CTYPE=en_US.iso88591 luit

(Puede usar cualquier otra configuración regional con la misma codificación, por ejemplo LC_CTYPE=es_ES.iso88591 luit).

Gilles 'SO- deja de ser malvado'
fuente
Gracias Gilles por esa maravillosa explicación, especialmente por explicar las dos indicaciones para LC_CTYPE.
Craconia
Volviendo a mi último caso: pensé que, dado que todos los nombres de archivo estaban codificados en latin1 más el hecho de que mi dispositivo de salida final, el que creaba los glifos (mi terminal) también estaba configurado para latin1, esperaba ver los archivos correctamente (independientemente de LC_CTYPE) ...
Craconia
Nunca se me ocurrió que lsconsideraría LC_CTYPE (configurado en UTF-8 en este caso) y realizaría algún tipo de validación de conjunto de caracteres: cada vez que ve algo no compatible con el conjunto de caracteres, escupiría un carácter específico (por ejemplo, "? "). Dije "validación" porque no realizará una "conversión" como lo hace luit. ¿Es asi?
Craconia
@ Craconia En el tercer caso, lsreemplaza los caracteres no imprimibles por ?. La mayoría de las cadenas codificadas en latin-1 que representan palabras reales tienen caracteres no imprimibles si se interpretan como UTF-8.
Gilles 'SO- deja de ser malvado'
5

En el caso # 2 y # 3, está mezclando dos codificaciones diferentes UTF-8 y Latin-1. En el caso n. ° 1, está utilizando Latin-1 para ambos, por lo que no tiene ningún problema.

El lscomando (y todos los demás programas que se comportan bien) usan la configuración LANG para determinar la codificación .

Puede mezclar dos idiomas diferentes, pero no debe mezclar dos codificaciones diferentes .

Asegúrese de que las variables de entorno LC_ * también usen la misma codificación que su variable LANG.

Como regla general, debe configurar su sistema hoy en día para usar solo UTF-8.

Si tiene que editar archivos de datos antiguos (p. Ej., Propiedades de Java), debe usar un editor especializado (p. Ej., Java ide) o garantizar la codificación con herramientas como iconvo 'recode ...

H.-Dirk Schmitt
fuente
Gracias. Sí, tengo planes de cambiarme a UTF-8 en el futuro cercano. Tengo un montón de nombres de archivo para convertir, además de muchos archivos de texto. iconv & convmv to the rescue ...
Craconia
0

Esto podría estar fuera de tu necesidad, pero ...

Resulta que en RHEL5, y probablemente antes, muchas de las páginas del manual, de alguna manera, por alguna razón de Dios, han sido asociadas. Es decir, la página de manual sin formato se ha convertido de su juego de caracteres nativo a ASCII de 7 bits. No importa lo que haga con LC y LANG, la página de manual latin1produce una página de manual que es efectivamente inútil. Todos los caracteres especiales (8 bits) dentro han sido reemplazados por marcadores de posición de 7 bits (generalmente ??). Esto me parece gracioso.

Pero la utf8versión de estas páginas de manual puede existir en el directorio específico del idioma. El truco es pedirlos por su nombre correcto. Por ejemplo, latin1 es en realidad iso_8859-1. Si hace una página de manual y sus configuraciones de LANG son correctas, verá lo que espera; la página del manual se encuentra en el subdirectorio específico del idioma ( en/man7/iso_8859-1.7). Pero si lo solicita iso-8859-1, por alguna razón, obtiene la versión ASCII.

Oteo
fuente