Auswirkung von $ LANG auf das Terminal


11

Ich versuche zu lernen, wie sich die $LANGVariable mit dem Gnome-Terminal (und seiner Voreinstellungsoption für die Zeichenkodierung) verhält. Ich habe iso8859-1 (latin1) als Hauptzeichensatz verwendet und alle meine Dateinamen sind als solche codiert.

Für die folgenden Tests werde ich ein ls -lVerzeichnis mit Zeichen mit spanischem Akzent in ihren Dateinamen erstellen:

Fall 1:

  • Gnome-Terminal konfiguriert für ISO-8859-1
  • LANG auf "en_US-iso8859-1" setzen
  • Ergebnis: Ich sehe alle Dateien korrekt

Fall 2:

  • Gnome-Terminal für UTF-8 konfiguriert
  • LANG auf "en_US-iso8859-1" setzen
  • Ergebnis: Ich sehe Müllzeichen für alle spanischen Zeichen. Dies wird erwartet, da ich die Zeichenkodierung für das Terminal geändert habe

Fall 3:

  • Gnome-Terminal konfiguriert für ISO-8859-1
  • LANG auf "en_US-UTF-8" setzen
  • Ergebnis: Ich sehe Müllzeichen für alle spanischen Zeichen.

Warum sehe ich in diesem letzten Fall verstümmelte Zeichen? Sollte die Ausgabe von ls die Dateinamen nicht so wie sie sind direkt an das Gnome-Terminal senden? Und da das Gnome-Terminal für ISO-8859-1 konfiguriert ist, hätte ich erwartet, dass sie richtig aussehen.

Für einen Moment dachte ich, dass Bash vielleicht meine $LANGVariable berücksichtigt und eine Konvertierung durchführt. Dann habe ich mein Terminal auf UTF-8 umgestellt, aber ich kann die Zeichen immer noch nicht richtig sehen. Ich habe sogar die Ausgabe von ls an xxd weitergeleitet und zu meiner Überraschung sehe ich die Dateien immer noch so codiert, wie sie sind: ISO-8859-1.

Zum Abschluss: Wenn mein Eintrag ISO-8859-1-Zeichen enthält und mein Terminalemulator für dieselbe Zeichencodierung konfiguriert ist: Wer führt die Konvertierung durch, wenn etwas LANGanderes festgelegt ist?

Vielen Dank für jede Hilfe, die Sie leisten können.

Craconia

Antworten:


5

Ihre Einstellung für LANGmuss mit der des Terminals übereinstimmen. Genauer gesagt muss Ihre Einstellung für LC_CTYPE(die Zeichencodierung) mit der Codierung des Terminals übereinstimmen, die anderen Gebietsschemaeinstellungen müssen nicht übereinstimmen. Die Codierung des Terminals wird normalerweise durch eine Option des Terminalemulators und nicht durch eine Gebietsschemavariable angegeben. Das LC_CTYPEkombiniert zwei Anzeigen: Es teilt Anwendungen mit, welche Codierung auf dem Terminal verwendet werden soll (sowohl für die Eingabe als auch für die Ausgabe), und es teilt Anwendungen mit, welche Codierung mit Dateien verwendet werden soll. In den Fällen 2 und 3 haben Sie angewiesen ls, die Ausgabe in einer anderen Codierung als die des Terminals anzuzeigen, sodass die Ausgabe verstümmelt ist.

Wenn Sie zu unterschiedlichen Zeiten mit UTF-8- und Latin-1-Codierungen arbeiten, konfigurieren Sie Ihr Terminal für die Verwendung von UTF-8. Dies sollte dazu führen LC_CTYPE, dass ein Wert festgelegt wird, der UTF-8 angibt. Überschreiben Sie diese Einstellung nicht. (Wenn der Terminalemulator nicht festgelegt ist LC_CTYPE, überschreiben Sie ihn in Ihrer Shell-Startdatei oder für Ihre gesamte Sitzung.) Verwenden Sie luit(in der X Utility Suite enthalten), um mit Latin-1-Daten in einem UTF-8-Terminal zu arbeiten .

LC_CTYPE=en_US.iso88591 luit

(Sie können jedes andere Gebietsschema mit derselben Codierung verwenden, z LC_CTYPE=es_ES.iso88591 luit.


Vielen Dank an Gilles für diese wunderbare Erklärung, insbesondere für die Erklärung der beiden Indikationen für LC_CTYPE.
Craconia

Zurück zu meinem letzten Fall: Da alle Dateinamen in latin1 codiert waren und mein letztes Ausgabegerät, das die Glyphen (mein Terminal) erstellt, auch für latin1 konfiguriert war, erwartete ich, dass die Dateien korrekt angezeigt werden (unabhängig von LC_CTYPE) ...
Craconia

Mir ist nie in den lsSinn gekommen , dass ich LC_CTYPE (in diesem Fall auf UTF-8 gesetzt) ​​in Betracht ziehen und eine Art Zeichensatzvalidierung durchführen würde: Wenn es etwas sieht, das nicht mit dem Zeichensatz kompatibel ist, spuckt es ein bestimmtes Zeichen aus (z. B. "? "). Ich sagte "Validierung", weil es keine "Konvertierung" durchführt, wie es Luit tut. Ist es so
Craconia

@Craconia Ersetzt im dritten Fall lsdie nicht druckbaren Zeichen durch ?. Die meisten in Latin-1 codierten Zeichenfolgen, die echte Wörter darstellen, haben nicht druckbare Zeichen, wenn sie als UTF-8 interpretiert werden.
Gilles 'SO - hör auf böse zu sein'

5

Im Fall Nr. 2 und Nr. 3 mischen Sie zwei verschiedene Codierungs-UTF-8 und Latin-1. In Fall 1 verwenden Sie Latin-1 für beide, sodass Sie kein Problem haben.

Der lsBefehl (und alle anderen gut verhaltenen Programme) verwenden die LANG-Einstellung zum Bestimmen der Codierung .

Sie können zwei verschiedene Sprachen mischen , aber Sie sollten nicht zwei verschiedene Codierungen mischen .

Stellen Sie sicher, dass die Umgebungsvariablen LC_ * dieselbe Codierung wie Ihre LANG-Variable verwenden.

Als Faustregel sollten Sie Ihr System heutzutage so konfigurieren, dass nur UTF-8 verwendet wird.

Wenn Sie altmodische Datendateien (z. B. Java-Eigenschaften) bearbeiten müssen, sollten Sie entweder einen speziellen Editor (z. B. Java-Ide) verwenden oder die Codierung mit Tools wie iconvoder `recode .. sicherstellen.


Vielen Dank. Ja, ich habe vor, in naher Zukunft auf UTF-8 umzusteigen. Ich habe eine Reihe von Dateinamen zum Konvertieren sowie viele, viele Textdateien. iconv & convmv zur Rettung ...
Craconia

0

Dies könnte außerhalb Ihres Bedarfs liegen, aber ...

Es stellt sich heraus, dass RHEL5 und wahrscheinlich schon früher viele der Manpages aus irgendeinem gd vorausgegangenen Grund auf den neuesten Stand gebracht wurden. Das heißt, die rohe Manpage wurde von ihrem nativen Zeichensatz in 7-Bit-ASCII konvertiert. Unabhängig davon, was Sie mit LC und LANG tun, erstellt die Manpage für latin1eine Manpage, die praktisch unbrauchbar ist. Alle darin enthaltenen Sonderzeichen (8-Bit) wurden (normalerweise ??) durch 7-Bit-Platzhalter ersetzt . Ich finde das komisch.

Die utf8Version dieser Manpages befindet sich jedoch möglicherweise im sprachspezifischen Verzeichnis. Der Trick besteht darin, sie mit ihrem richtigen Namen zu fragen. Zum Beispiel ist latin1 tatsächlich iso_8859-1. Wenn Sie eine Manpage darauf erstellen und Ihre LANG-Einstellungen korrekt sind, sehen Sie, was Sie erwarten. Die Manpage befindet sich im sprachspezifischen Unterverzeichnis ( en/man7/iso_8859-1.7). Wenn Sie jedoch iso-8859-1aus irgendeinem Grund danach fragen , erhalten Sie die ASCII-Version.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.