Beberapa pertanyaan tentang pengkodean karakter sistem file di linux

12

Karena banyak pertukaran file berfungsi antara Windows ( GBK encoding) dan Linux ( UTF-8 encoding), ia akan menghadapi masalah pengkodean karakter dengan mudah, seperti:

  • file zip / tar yang namanya berisi karakter Cina di sistem Windows, unzip / untar di sistem Linux.
  • menjalankan migrasi aplikasi web lawas java (dirancang pada sistem Windows, menggunakan pengkodean GBK di JSP) yang menulis file yang diberi nama pengodean GBK ke disk.
  • ftp dapatkan / letakkan file yang diberi nama GBK-encoding antara Windows FTP server dan klien Linux.
  • beralih lingkungan LANG di Linux.

Masalah umum yang disebutkan sebelumnya adalah mencari / penamaan file. Setelah googled, saya mendapat artikel Menggunakan Unicode di Linux http://www.linux.com/archive/feed/39912 , katanya:

sistem operasi dan banyak utilitas tidak menyadari karakter apa yang mewakili byte dalam nama file.

Jadi, dimungkinkan untuk memiliki 2 file 中文 .txt dengan penyandian berbeda:

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

Pertanyaan:

  1. Apakah mungkin untuk mengkonfigurasi sistem file linux menggunakan pengkodean karakter tetap (seperti NTFS menggunakan UTF-16 secara internal) untuk menyimpan nama file terlepas dari lingkungan LANG / LC_ALL?
  2. Atau, yang sebenarnya ingin saya tanyakan adalah: Apakah mungkin membiarkan nama file 中文 .txt ( $'\xe4\xb8\xad\xe6\x96\x87.txt') di lingkungan zh_CN.UTF-8 dan nama file 中文 .txt ( $'\xd6\xd0\xce\xc4.txt') di lingkungan zh_CN.GBK merujuk ke file yang sama ?
  3. Jika tidak dapat dikonfigurasi, apakah mungkin untuk menambal kernel untuk menerjemahkan pengkodean karakter antara sistem file dan lingkungan saat ini (hanya pertanyaan, bukan meminta implementasi)? dan berapa banyak efek kinerja jika itu memungkinkan?
LiuYan 刘 研
sumber
Anda bisa mengatasi masalah dari sisi Windows dengan menggunakan Cygwin 1.7, yang tidak secara otomatis menerjemahkan antara pengkodean UTF-16 sistem berkas dan pengkodean apa pun yang telah ditentukan dalam pengaturan lokal. Standarnya adalah UTF-8, jadi misalnya Cygwin tar akan menyandikan nama file sebagai UTF-8.
ak2
@ ak2 Terima kasih, Cygwin benar-benar baik, saya sudah menggunakannya selama bertahun-tahun. Case tar / zip hanyalah sebuah contoh, dalam lingkungan nyata, file zip / tar dapat dibuat oleh orang lain (seperti mengunduh file dari internet).
LiuYan 刘 研

Jawaban:

8

Saya telah sedikit merumuskan kembali pertanyaan Anda, untuk alasan yang seharusnya tampak jelas ketika Anda membacanya secara berurutan.

1. Apakah mungkin untuk mengkonfigurasi sistem file linux menggunakan pengkodean karakter tetap untuk menyimpan nama file terlepas dari lingkungan LANG / LC_ALL?

Tidak, ini tidak mungkin: seperti yang Anda sebutkan dalam pertanyaan Anda, nama file UNIX hanyalah urutan byte; kernel tidak tahu apa-apa tentang pengkodean, yang sepenuhnya merupakan konsep ruang pengguna (yaitu, level aplikasi).

Dengan kata lain, kernel tidak tahu apa-apa tentang LANG/ LC_*, jadi tidak bisa menerjemahkan.

2. Apakah mungkin untuk membiarkan nama file yang berbeda merujuk ke file yang sama?

Anda dapat memiliki beberapa entri direktori yang merujuk ke file yang sama; Anda dapat melakukannya melalui tautan keras atau tautan simbolik .

Perlu diketahui, bahwa nama file yang tidak valid dalam pengkodean saat ini (mis. String karakter GBK Anda saat Anda bekerja di lokal UTF-8) akan ditampilkan dengan buruk, jika tidak sama sekali.

3. Apakah mungkin untuk menambal kernel untuk menerjemahkan pengkodean karakter antara sistem file dan lingkungan saat ini?

Anda tidak dapat menambal kernel untuk melakukan ini (lihat 1.), tetapi Anda bisa -dalam teori-menambal perpustakaan C (misalnya, glibc) untuk melakukan terjemahan ini, dan selalu mengonversi nama file ke UTF-8 ketika memanggil kernel, dan mengonversinya kembali ke pengkodean saat ini ketika membaca nama file dari kernel.

Pendekatan yang lebih sederhana adalah dengan menulis sistem file overlay dengan FUSE , yang hanya mengalihkan permintaan sistem file ke lokasi lain setelah mengonversi nama file ke / dari UTF-8. Idealnya Anda dapat me-mount sistem file ini ~/trans, dan ketika akses dibuat untuk ~/trans/a/GBK/encoded/pathkemudian filesystem FUSE benar-benar mengakses /a/UTF-8/encoded/path.

Namun, masalah dengan pendekatan ini adalah: apa yang Anda lakukan dengan file yang sudah ada pada sistem file Anda dan tidak disandikan UTF-8? Anda tidak bisa begitu saja meneruskannya tanpa diterjemahkan, karena Anda tidak akan tahu cara mengubahnya; Anda tidak dapat memotongnya dengan menerjemahkan urutan karakter yang tidak valid ?karena itu dapat membuat konflik ...

Riccardo Murri
sumber
4
Sistem file overlay seperti itu ada: Convmvfs .
Gilles 'SO- berhenti menjadi jahat'
1

Yang dapat Anda lakukan adalah membatasi jumlah lokal yang didukung hanya untuk lokal UTF-8.

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

Biarkan aku menjadi
sumber
2
Secara pribadi, saya berharap hanya ada 1 pengkodean charset (UTF-8) di dunia, tetapi ada aplikasi warisan yang masih berjalan, dan interoperabilitas antara Windows dan Linux harus dicapai, kebanyakan orang harus menghadapi mimpi buruk ini.
LiuYan 刘 研