Efek $ LANG pada terminal

11

Saya mencoba mempelajari bagaimana $LANGvariabel berperilaku dengan terminal gnome (dan opsi preferensi pengkodean karakternya). Saya telah menggunakan iso8859-1 (latin1) sebagai set karakter utama saya dan semua nama file saya dikodekan seperti itu.

Untuk pengujian berikut saya akan melakukan ls -ldirektori dengan karakter beraksen Spanyol di nama file mereka:

Kasus 1:

  • gnome-terminal dikonfigurasi untuk ISO-8859-1
  • LANG set ke "en_US-iso8859-1"
  • Hasil: Saya melihat semua file dengan benar

Kasus # 2:

  • gnome-terminal dikonfigurasi untuk UTF-8
  • LANG set ke "en_US-iso8859-1"
  • Hasil: Saya melihat karakter sampah untuk semua karakter Spanyol. Ini diharapkan ketika saya mengubah pengkodean karakter untuk terminal

Kasus # 3:

  • gnome-terminal dikonfigurasi untuk ISO-8859-1
  • LANG set ke "en_US-UTF-8"
  • Hasil: Saya melihat karakter sampah untuk semua karakter Spanyol.

Mengapa dalam kasus terakhir ini saya melihat karakter kacau? Bukankah seharusnya output dari ls mengirim nama file langsung ke terminal gnome? Dan karena gnome-terminal dikonfigurasi untuk ISO-8859-1, saya akan berharap mereka terlihat benar.

Untuk sesaat saya berpikir, mungkin, mungkin bash sedang mempertimbangkan $LANGvariabel saya dan melakukan beberapa konversi. Kemudian saya pindah terminal saya ke UTF-8 tetapi saya masih tidak dapat melihat karakter dengan benar. Saya bahkan menyalurkan output ls ke xxd dan yang mengejutkan saya, saya masih melihat file-file tersebut disandikan sebagai: ISO-8859-1.

Untuk menyelesaikannya: Jika daftar saya mengandung karakter ISO-8859-1 dan emulator terminal saya dikonfigurasi untuk pengkodean karakter yang sama: Siapa yang melakukan konversi ketika LANGdiatur sebaliknya?

Terima kasih atas bantuan yang Anda berikan.

Craconia

Craconia
sumber

Jawaban:

5

Pengaturan Anda untuk LANGharus cocok dengan terminal. Lebih tepatnya, pengaturan Anda untuk LC_CTYPE(pengkodean karakter) harus cocok dengan pengkodean terminal, pengaturan lokal lainnya tidak perlu cocok. Dan pengkodean terminal biasanya ditentukan oleh opsi emulator terminal dan bukan oleh variabel lokal. The LC_CTYPEmenggabungkan dua indikasi: ia memberitahu aplikasi apa pengkodean untuk digunakan pada terminal (baik untuk input dan output), dan memberitahu aplikasi apa pengkodean untuk digunakan dengan file. Dalam kasus 2 dan 3, Anda telah diberitahu lsuntuk menampilkan output dalam penyandian yang berbeda dari terminal, sehingga hasilnya kacau.

Jika Anda bekerja dengan pengkodean UTF-8 dan latin-1 pada waktu yang berbeda, konfigurasikan terminal Anda untuk menggunakan UTF-8. Ini harus menyebabkannya diatur LC_CTYPEke nilai yang mengindikasikan UTF-8; jangan timpa pengaturan ini. (Jika emulator terminal tidak disetel LC_CTYPE, jangan menimpanya di file startup shell Anda atau untuk seluruh sesi Anda.) Untuk bekerja dengan data latin-1 di terminal UTF-8, gunakan luit(termasuk dalam X utility suite).

LC_CTYPE=en_US.iso88591 luit

(Anda dapat menggunakan lokal lain dengan penyandian yang sama, misalnya LC_CTYPE=es_ES.iso88591 luit.)

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Terima kasih Gilles untuk penjelasan yang luar biasa itu, terutama karena menjelaskan dua indikasi untuk LC_CTYPE.
Craconia
Kembali ke kasus terakhir saya: Saya pikir, karena semua nama file dikodekan dalam latin1 ditambah fakta bahwa perangkat keluaran akhir saya, yang menciptakan mesin terbang (terminal saya) juga dikonfigurasi untuk latin1, saya berharap untuk melihat file dengan benar (terlepas dari LC_CTYPE) ...
Craconia
Tidak pernah terpikir oleh saya bahwa lsakan mempertimbangkan LC_CTYPE (set ke UTF-8 dalam kasus ini) dan akan melakukan semacam validasi karakter-set: setiap kali melihat sesuatu yang tidak kompatibel dengan set karakter, ia akan meludah karakter tertentu (misalnya "? "). Saya mengatakan "validasi" karena tidak akan melakukan "konversi" seperti yang dilakukan luit. Apakah seperti ini?
Craconia
@Craconia Dalam kasus ketiga, lsganti karakter yang tidak patut ditulis oleh ?. Sebagian besar string yang dikodekan dalam latin-1 yang mewakili kata-kata nyata memiliki karakter yang tidak patut jika ditafsirkan sebagai UTF-8.
Gilles 'SO- stop being evil'
5

Dalam kasus # 2 dan # 3 Anda mencampur dua pengkodean berbeda UTF-8 dan Latin-1. Dalam hal # 1 Anda menggunakan Latin-1 untuk keduanya, jadi Anda tidak memiliki masalah.

The lsperintah (dan semua programms baik berperilaku lain) menggunakan pengaturan LANG untuk menentukan encoding .

Anda dapat mencampur dua Bahasa yang berbeda, tetapi Anda tidak harus mencampur dua pengkodean yang berbeda .

Pastikan variabel lingkungan LC_ * juga menggunakan pengkodean yang sama dengan variabel LANG Anda.

Sebagai aturan praktis Anda harus mengkonfigurasi sistem Anda saat ini untuk hanya menggunakan UTF-8.

Jika Anda harus mengedit file data kuno (mis. Properti java) Anda harus menggunakan editor khusus (mis. Java ide) atau memastikan pengkodean dengan alat seperti iconvatau `kodek ulang ..

H.-Dirk Schmitt
sumber
Terima kasih. Ya, saya memiliki rencana untuk beralih ke UTF-8 dalam waktu dekat. Punya banyak nama file untuk dikonversi dan banyak file teks. iconv & convmv to the rescue ...
Craconia
0

Ini mungkin di luar kebutuhan Anda, tetapi ....

Ternyata di RHEL5, dan mungkin sebelumnya, banyak halaman manual entah bagaimana untuk alasan ditinggalkan, telah diasosiasikan. Yaitu, halaman manual raw telah dikonversi dari karakter aslinya diatur ke 7-bit ASCII. Tidak peduli apa yang Anda lakukan dengan LC dan LANG, halaman manual untuk latin1menghasilkan halaman manual yang secara efektif tidak berguna. Semua karakter khusus (8-bit) di dalam telah diganti dengan placeholder 7-bit (biasanya ??). Saya menemukan ini lucu.

Tetapi utf8versi halaman manual ini mungkin ada di direktori khusus bahasa. Kuncinya adalah meminta mereka dengan nama kanan mereka. Misalnya, latin1 sebenarnya iso_8859-1. Jika Anda melakukan halaman manual di dalamnya, dan pengaturan LANG Anda benar, Anda melihat apa yang Anda harapkan; halaman manual ditemukan dalam subdir bahasa khusus ( en/man7/iso_8859-1.7). Tetapi jika Anda meminta iso-8859-1, untuk beberapa alasan, Anda mendapatkan versi ASCII.

Otheus
sumber