Mehrere Fragen zur Dateisystem-Zeichenkodierung unter Linux


12

Aufgrund des umfangreichen Dateiaustauschs zwischen Windows ( GBK- Codierung) und Linux ( UTF-8- Codierung) kann es leicht zu Problemen bei der Zeichencodierung kommen, z.

  • zip / tar-Dateien, deren Name unter Windows chinesische Zeichen enthält, entpacken / entpacken Sie sie unter Linux.
  • Führen Sie eine migrierte ältere Java-Webanwendung aus (entwickelt auf einem Windows-System mit GBK-Codierung in JSP), die mit GBK-Codierung benannte Dateien auf die Festplatte schreibt.
  • FTP holt / legt Dateien mit GBK-Kodierung zwischen dem Windows-FTP-Server und dem Linux-Client ab.
  • LANG-Umgebung unter Linux wechseln.

Das häufigste Problem der oben genannten sind das Suchen / Benennen von Dateien. Nach gegoogelt, ich einen Artikel bekam Verwendung von Unicode in Linux http://www.linux.com/archive/feed/39912 , hieß es:

Das Betriebssystem und viele Dienstprogramme erkennen nicht, für welche Zeichen die Bytes in den Dateinamen stehen.

So ist es möglich, 2 xt .txt-Dateien mit unterschiedlicher Kodierung zu haben:

[root@fedora test]# ls
????  中文
[root@fedora test]# ls | iconv -f GBK
中文
涓iconv: illegal input sequence at position 7
[root@fedora test]# ls 中文 && ls $'\xd6\xd0\xce\xc4'|iconv -f gbk
中文
中文

Fragen:

  1. Ist es möglich, das Linux-Dateisystem mit fester Zeichenkodierung zu konfigurieren (wie NTFS intern UTF-16 verwenden), um Dateinamen unabhängig von der LANG / LC_ALL-Umgebung zu speichern?
  2. Oder, was ich eigentlich fragen möchte, ist: Ist es möglich, den Dateinamen 中文 .txt ( $'\xe4\xb8\xad\xe6\x96\x87.txt') in der Umgebung von zh_CN.UTF-8 und den Dateinamen 中文 .txt ( $'\xd6\xd0\xce\xc4.txt') in der Umgebung von zh_CN.GBK auf dieselbe Datei zu verweisen ?
  3. Wenn es nicht konfigurierbar ist, ist es dann möglich, den Kernel zu patchen, um die Zeichenkodierung zwischen Dateisystem und aktueller Umgebung zu übersetzen (nur eine Frage, keine Implementierung anfordern)? und wie viel leistung wirkt sich aus, wenn es möglich ist?

Sie können das Problem von Windows aus lösen, indem Sie Cygwin 1.7 verwenden, das automatisch zwischen der UTF-16-Codierung des Dateisystems und der in den Ländereinstellungen angegebenen Codierung übersetzt. Der Standardwert ist UTF-8, sodass Cygwin tar beispielsweise Dateinamen wie UTF-8 codiert.
Ak2

@ ak2 Danke, Cygwin ist wirklich gut, ich benutze es schon seit Jahren. Der Fall tar / zip ist nur ein Beispiel. In einer realen Umgebung können die zip / tar-Dateien von anderen erstellt werden (z. B. Herunterladen einer Datei aus dem Internet).
LiuYan 刘 研

Antworten:


8

Ich habe Ihre Fragen ein wenig umformuliert, aus Gründen, die offensichtlich erscheinen sollten, wenn Sie sie nacheinander lesen.

1. Ist es möglich, das Linux-Dateisystem unabhängig von der LANG / LC_ALL-Umgebung mit fester Zeichencodierung zu konfigurieren, um Dateinamen zu speichern?

Nein, das ist nicht möglich: Wie Sie in Ihrer Frage erwähnt haben, ist ein UNIX-Dateiname nur eine Folge von Bytes. Der Kernel weiß nichts über die Kodierung, die ein Konzept auf Benutzerebene (dh auf Anwendungsebene) darstellt.

Mit anderen Worten, der Kernel weiß nichts über LANG/ LC_*und kann daher nicht übersetzen.

2. Können verschiedene Dateinamen auf dieselbe Datei verweisen?

Sie können mehrere Verzeichniseinträge haben, die auf dieselbe Datei verweisen. Sie können das durch harte Links oder symbolische Links machen .

Beachten Sie jedoch, dass die Dateinamen, die in der aktuellen Codierung nicht gültig sind (z. B. Ihre GBK-Zeichenfolge, wenn Sie in einem UTF-8-Gebietsschema arbeiten), wenn überhaupt schlecht angezeigt werden.

3. Ist es möglich, den Kernel zu patchen, um die Zeichenkodierung zwischen Dateisystem und aktueller Umgebung zu übersetzen?

Sie können den Kernel dazu nicht patchen (siehe 1.), aber Sie könnten theoretisch die C-Bibliothek patchen (z. B. glibc), um diese Übersetzung durchzuführen, und immer die Dateinamen in UTF-8 konvertieren, wenn der Kernel aufgerufen wird. und konvertieren Sie sie zurück in die aktuelle Kodierung, wenn ein Dateiname aus dem Kernel gelesen wird.

Ein einfacherer Ansatz könnte darin bestehen, ein Overlay-Dateisystem mit FUSE zu schreiben , das alle Dateisystemanforderungen nach der Konvertierung des Dateinamens in / von UTF-8 an einen anderen Speicherort umleitet. Idealerweise können Sie dieses Dateisystem einbinden ~/trans, und wenn ein Zugriff darauf erfolgt, ~/trans/a/GBK/encoded/pathgreift das FUSE-Dateisystem tatsächlich zu /a/UTF-8/encoded/path.

Das Problem bei diesen Ansätzen ist jedoch: Was machen Sie mit Dateien, die bereits in Ihrem Dateisystem vorhanden und nicht UTF-8-codiert sind? Sie können sie nicht einfach unübersetzt weitergeben, da Sie dann nicht wissen, wie Sie sie konvertieren sollen. Sie können sie nicht entstellen, indem Sie ungültige Zeichenfolgen in übersetzen, ?da dies zu Konflikten führen kann ...


4
Es gibt ein solches Overlay-Dateisystem: Convmvfs .
Gilles 'SO - hör auf, böse zu sein'

1

Sie können die Anzahl der unterstützten Gebietsschemas auf UTF-8-Gebietsschemas beschränken.

http://www.fifi.org/cgi-bin/man2html/usr/share/man/man5/locale.gen.5


2
Persönlich würde ich mir wünschen, dass es nur 1 Zeichensatzkodierung (UTF-8) auf der Welt gibt, aber es werden noch Legacy-Anwendungen ausgeführt, und die Interoperabilität zwischen Windows und Linux muss gewährleistet sein. Die meisten Menschen müssen sich diesem Albtraum stellen.
LiuYan 刘 研
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.