Diverse domande sulla codifica dei caratteri del file system su Linux


12

A causa di molte operazioni di scambio di file tra Windows ( codifica GBK ) e Linux ( codifica UTF-8 ), si verificheranno facilmente problemi di codifica dei caratteri, come:

  • file zip / tar il cui nome contiene caratteri cinesi sul sistema Windows, decomprimilo / decomprimilo nel sistema Linux.
  • eseguire un'applicazione Web java legacy migrata (progettata su sistema Windows, utilizzando la codifica GBK in JSP) che scrive su disco file con nome codifica GBK.
  • ftp ottiene / inserisce file con nome codifica GBK tra il server FTP di Windows e il client Linux.
  • cambia ambiente LANG in Linux.

Il problema comune di cui sopra è la localizzazione / denominazione dei file. Dopo aver cercato su Google, ho ricevuto un articolo su Unicode in Linux http://www.linux.com/archive/feed/39912 , che diceva:

il sistema operativo e molte utility non comprendono quali caratteri rappresentano i byte nei nomi dei file.

Quindi, è possibile avere 2 file 中文 .txt con codifica diversa:

[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
中文
中文

Domande:

  1. È possibile configurare il filesystem linux usando una codifica a caratteri fissi (come NTFS usa internamente UTF-16) per memorizzare i nomi dei file indipendentemente dall'ambiente LANG / LC_ALL?
  2. Oppure, ciò che voglio effettivamente chiedere è: è possibile lasciare che il nome file 中文 .txt ( $'\xe4\xb8\xad\xe6\x96\x87.txt') nell'ambiente zh_CN.UTF-8 e il nome file 中文 .txt ( $'\xd6\xd0\xce\xc4.txt') nell'ambiente zh_CN.GBK si riferiscano allo stesso file ?
  3. Se non è configurabile, allora è possibile patchare il kernel per tradurre la codifica dei caratteri tra il file system e l'ambiente corrente (solo una domanda, non richiedere l'implementazione)? e quante prestazioni hanno effetto se è possibile?

È possibile affrontare il problema dal lato Windows utilizzando Cygwin 1.7, che traduce automaticamente tra la codifica UTF-16 del filesystem e qualunque codifica sia stata specificata nelle impostazioni locali. L'impostazione predefinita è UTF-8, quindi per esempio Cygwin tar codificherebbe i nomi dei file come UTF-8.
ak2

@ ak2 Grazie, Cygwin è davvero bravo, lo uso da anni. Il caso tar / zip è solo un esempio, in un ambiente reale, i file zip / tar possono essere creati da altri (come scaricare un file da internet).
LiuYan 刘 研

Risposte:


8

Ho riformulato un po 'le tue domande, per ragioni che dovrebbero apparire evidenti quando le leggi in sequenza.

1. È possibile configurare il filesystem linux usando la codifica a caratteri fissi per memorizzare i nomi dei file indipendentemente dall'ambiente LANG / LC_ALL?

No, questo non è possibile: come accennato nella tua domanda, un nome di file UNIX è solo una sequenza di byte; il kernel non sa nulla della codifica, che è interamente un concetto di spazio utente (cioè a livello di applicazione).

In altre parole, il kernel non sa nulla di LANG/ LC_*, quindi non può tradurre.

2. È possibile lasciare che nomi di file diversi facciano riferimento allo stesso file?

Puoi avere più voci di directory che si riferiscono allo stesso file; puoi farlo attraverso collegamenti reali o collegamenti simbolici .

Tenere presente, tuttavia, che i nomi dei file che non sono validi nella codifica corrente (ad esempio, la stringa di caratteri GBK quando si lavora in una locale UTF-8) verranno visualizzati male, se non del tutto.

3. È possibile patchare il kernel per tradurre la codifica dei caratteri tra il file system e l'ambiente attuale?

Non puoi patchare il kernel per fare questo (vedi 1.), ma potresti - in teoria - patchare la libreria C (ad esempio, glibc) per eseguire questa traduzione e convertire sempre i nomi dei file in UTF-8 quando chiama il kernel, e riconvertirli nella codifica corrente quando legge un nome di file dal kernel.

Un approccio più semplice potrebbe essere quello di scrivere un filesystem overlay con FUSE , che reindirizza qualsiasi richiesta del filesystem in un'altra posizione dopo aver convertito il nome del file in / da UTF-8. Idealmente, potresti montare questo filesystem ~/transe, quando viene effettuato l'accesso, ~/trans/a/GBK/encoded/pathil filesystem FUSE accede davvero /a/UTF-8/encoded/path.

Tuttavia, il problema con questi approcci è: cosa fai con i file che già esistono sul tuo filesystem e che non sono codificati UTF-8? Non puoi semplicemente passarli non tradotti, perché poi non sai come convertirli; non puoi manipolarli traducendo sequenze di caratteri non validi ?perché ciò potrebbe creare conflitti ...


4
Esiste un tale filesystem overlay: Convmvfs .
Gilles 'SO- smetti di essere malvagio' il

1

Quello che puoi fare è limitare la quantità di impostazioni locali supportate solo alle impostazioni locali UTF-8.

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


2
Personalmente, vorrei che ci fosse solo 1 codifica set di caratteri (UTF-8) nel mondo, ma ci sono ancora applicazioni legacy in esecuzione e l'interoperabilità tra Windows e Linux deve essere raggiunta, la maggior parte delle persone deve affrontare questo incubo.
LiuYan 刘 研
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.