Effet de $ LANG sur le terminal

11

J'essaie d' apprendre comment la $LANGvariable se comporte avec gnome-terminal (et son option de préférence d'encodage de caractères). J'utilise iso8859-1 (latin1) comme jeu de caractères principal et tous mes noms de fichiers sont codés comme tels.

Pour les tests suivants, je ferai ls -lun répertoire avec des caractères accentués espagnols dans leurs noms de fichiers:

Cas 1:

  • gnome-terminal configuré pour ISO-8859-1
  • LANG réglé sur "en_US-iso8859-1"
  • Résultat: je vois tous les fichiers correctement

Cas n ° 2:

  • gnome-terminal configuré pour UTF-8
  • LANG réglé sur "en_US-iso8859-1"
  • Résultat: je vois des caractères inutiles pour tous les caractères espagnols. Cela est attendu car j'ai changé l'encodage des caractères pour le terminal

Cas n ° 3:

  • gnome-terminal configuré pour ISO-8859-1
  • LANG mis à "en_US-UTF-8"
  • Résultat: je vois des caractères inutiles pour tous les caractères espagnols.

Pourquoi est-ce que dans ce dernier cas, je vois des caractères tronqués? La sortie de ls ne devrait-elle pas envoyer les noms de fichiers directement à gnome-terminal tels qu'ils sont? Et puisque gnome-terminal est configuré pour ISO-8859-1, je m'attendais à ce qu'ils semblent corrects.

Pendant un moment, j'ai pensé que, peut-être, bash envisageait ma $LANGvariable et effectuait une conversion. Ensuite, j'ai changé mon terminal en UTF-8 mais je ne vois toujours pas les bons caractères. J'ai même canalisé la sortie de ls vers xxd et à ma grande surprise, je vois toujours les fichiers encodés tels qu'ils sont: ISO-8859-1.

Pour conclure: si ma liste contient des caractères ISO-8859-1 et que mon émulateur de terminal est configuré pour le même codage de caractères: qui fait la conversion quand LANGest défini autrement?

Merci pour toute l'aide que vous pouvez apporter.

Craconia

Craconia
la source

Réponses:

5

Votre réglage pour LANGdoit correspondre à celui du terminal. Plus précisément, votre paramètre pour LC_CTYPE(l'encodage des caractères) doit correspondre à l'encodage du terminal, les autres paramètres régionaux n'ont pas besoin de correspondre. Et l'encodage du terminal est généralement spécifié par une option de l'émulateur de terminal et non par une variable locale. Le LC_CTYPEcombine deux indications: il indique aux applications quel encodage utiliser sur le terminal (à la fois pour l'entrée et la sortie), et il indique aux applications quel encodage utiliser avec les fichiers. Dans les cas 2 et 3, vous avez indiqué lsd'afficher la sortie dans un codage différent de celui du terminal, de sorte que la sortie est tronquée.

Si vous travaillez à des moments différents avec les encodages UTF-8 et latin-1, configurez votre terminal pour utiliser UTF-8. Cela devrait l'amener à définir LC_CTYPEune valeur indiquant UTF-8; ne remplacez pas ce paramètre. (Si l'émulateur de terminal n'est pas défini LC_CTYPE, remplacez-le dans votre fichier de démarrage du shell ou pour toute votre session.) Pour travailler avec des données latin-1 dans un terminal UTF-8, utilisez luit(inclus dans la suite d'utilitaires X).

LC_CTYPE=en_US.iso88591 luit

(Vous pouvez utiliser n'importe quel autre paramètre régional avec le même codage, par exemple LC_CTYPE=es_ES.iso88591 luit.)

Gilles 'SO- arrête d'être méchant'
la source
Merci Gilles pour cette merveilleuse explication, surtout pour avoir expliqué les deux indications pour LC_CTYPE.
Craconia
Pour en revenir à mon dernier cas: je pensais que, puisque tous les noms de fichiers étaient encodés en latin1 plus le fait que mon périphérique de sortie final, celui créant les glyphes (mon terminal) était également configuré pour latin1, je m'attendais à voir les fichiers correctement (indépendamment de LC_CTYPE) ...
Craconia
Il ne m'est jamais venu à l' lsesprit que considérer LC_CTYPE (défini sur UTF-8 dans ce cas) et effectuerait une sorte de validation de jeu de caractères: chaque fois qu'il verrait quelque chose de non compatible avec le jeu de caractères, il cracherait un caractère spécifique (par exemple "? "). J'ai dit "validation" car il n'effectuera pas de "conversion" comme le fait Luit. C'est comme ça?
Craconia
@Craconia Dans le troisième cas, lsremplace les caractères non imprimables par ?. La plupart des chaînes codées en latin-1 qui représentent des mots réels ont des caractères non imprimables si elles sont interprétées comme UTF-8.
Gilles 'SO- arrête d'être méchant'
5

Dans le cas # 2 et # 3, vous mélangez deux encodages différents UTF-8 et Latin-1. Dans le cas # 1, vous utilisez Latin-1 pour les deux, donc vous n'avez pas de problème.

La lscommande (et tous les autres programmes qui se comportent bien) utilisent le paramètre LANG pour déterminer l' encodage .

Vous pouvez mélanger deux langues différentes, mais vous ne devez pas mélanger deux encodages différents .

Assurez-vous que les variables d'environnement LC_ * utilisent également le même codage que votre variable LANG.

En règle générale, vous devez configurer votre système de nos jours pour utiliser uniquement UTF-8.

Si vous devez éditer des fichiers de données à l'ancienne (par exemple, les propriétés java), vous devez soit utiliser un éditeur spécialisé (par exemple, java ide) ou assurer l'encodage avec des outils comme iconvou `recode ..

H.-Dirk Schmitt
la source
Merci. Oui, j'ai l'intention de passer à l'UTF-8 dans un avenir proche. Vous avez un tas de noms de fichiers à convertir ainsi que de nombreux fichiers texte. iconv & convmv à la rescousse ...
Craconia
0

Cela pourrait être en dehors de vos besoins, mais ...

Il s'avère dans RHEL5, et probablement avant, de nombreuses pages de manuel ont été en quelque sorte pour une raison abandonnée par gd, établies. Autrement dit, la page de manuel brute a été convertie de son jeu de caractères natif en ASCII 7 bits. Peu importe ce que vous faites avec LC et LANG, la page de manuel de latin1produit une page de manuel qui est effectivement inutile. Tous les caractères spéciaux (8 bits) à l'intérieur ont été remplacés par des espaces réservés 7 bits (généralement ??). Je trouve ça hilarant.

Mais la utf8version de ces pages de manuel peut exister dans le répertoire spécifique à la langue. L'astuce consiste à les demander par leur bon nom. Par exemple, latin1 est en fait iso_8859-1. Si vous faites une page de manuel dessus et que vos paramètres LANG sont corrects, vous voyez ce que vous attendez; la page de manuel se trouve dans le sous-répertoire spécifique à la langue ( en/man7/iso_8859-1.7). Mais si vous demandez iso-8859-1, pour une raison quelconque, vous obtenez la version ASCII.

Otheus
la source