Ảnh hưởng của $ LANG trên thiết bị đầu cuối


11

Tôi đang cố gắng tìm hiểu cách $LANGbiến hoạt động với gnome-terminal (và tùy chọn tùy chọn mã hóa ký tự của nó). Tôi đã sử dụng iso8859-1 (latin1) làm bộ ký tự chính của mình và tất cả tên tệp của tôi được mã hóa như vậy.

Đối với các thử nghiệm sau đây, tôi sẽ thực hiện ls -lmột thư mục với các ký tự có dấu tiếng Tây Ban Nha trong tên tệp của họ:

Trường hợp 1:

  • gnome-terminal được cấu hình cho ISO-8859-1
  • LANG được đặt thành "en_US-iso8859-1"
  • Kết quả: Tôi thấy tất cả các tệp chính xác

Trường hợp 2

  • gnome-terminal được cấu hình cho UTF-8
  • LANG được đặt thành "en_US-iso8859-1"
  • Kết quả: Tôi thấy các ký tự rác cho tất cả các ký tự Tây Ban Nha. Điều này được mong đợi khi tôi thay đổi mã hóa ký tự cho thiết bị đầu cuối

Trường hợp # 3:

  • gnome-terminal được cấu hình cho ISO-8859-1
  • LANG được đặt thành "en_US-UTF-8"
  • Kết quả: Tôi thấy các ký tự rác cho tất cả các ký tự Tây Ban Nha.

Tại sao trong trường hợp cuối cùng này, tôi thấy các nhân vật bị cắt xén? Không phải đầu ra của ls gửi tên tệp thẳng đến gnome-terminal như chúng phải không? Và vì gnome-terminal được cấu hình cho ISO-8859-1, tôi sẽ mong họ nhìn đúng.

Trong một khoảnh khắc tôi nghĩ rằng, có lẽ, có lẽ bash đang xem xét $LANGbiến của tôi và thực hiện một số chuyển đổi. Sau đó, tôi chuyển thiết bị đầu cuối của mình sang UTF-8 nhưng tôi vẫn không thể nhìn thấy các ký tự đúng. Tôi thậm chí đã chuyển đầu ra của ls sang xxd và thật ngạc nhiên tôi vẫn thấy các tệp được mã hóa như chúng là: ISO-8859-1.

Để kết thúc: Nếu danh sách của tôi chứa các ký tự ISO-8859-1 và trình giả lập thiết bị đầu cuối của tôi được định cấu hình cho cùng một mã hóa ký tự: Ai đang thực hiện chuyển đổi khi LANGđược đặt khác?

Cảm ơn vì bất kì sự giúp đỡ nào của bạn.

Craconia

Câu trả lời:


5

Cài đặt của bạn LANGphải phù hợp với thiết bị đầu cuối. Chính xác hơn, cài đặt của bạn cho LC_CTYPE(mã hóa ký tự) phải khớp với mã hóa của thiết bị đầu cuối, các cài đặt ngôn ngữ khác không cần phải khớp. Và mã hóa của thiết bị đầu cuối thường được chỉ định bởi một tùy chọn của trình giả lập thiết bị đầu cuối chứ không phải bởi một biến cục bộ. Kết LC_CTYPEhợp hai chỉ dẫn: nó cho các ứng dụng biết nên sử dụng mã hóa nào trên thiết bị đầu cuối (cả cho đầu vào và đầu ra) và nó cho các ứng dụng biết mã hóa nào sẽ sử dụng với các tệp. Trong trường hợp 2 và 3, bạn đã yêu lscầu hiển thị đầu ra ở dạng mã hóa khác với đầu cuối, vì vậy đầu ra bị cắt xén.

Nếu bạn làm việc với cả mã hóa UTF-8 và latin-1 vào các thời điểm khác nhau, hãy định cấu hình thiết bị đầu cuối của bạn để sử dụng UTF-8. Điều này sẽ khiến nó được đặt thành LC_CTYPEgiá trị cho biết UTF-8; không ghi đè cài đặt này. (Nếu trình giả lập thiết bị đầu cuối không được đặt LC_CTYPE, hãy ghi đè lên tệp khởi động hệ vỏ của bạn hoặc cho toàn bộ phiên của bạn.) Để làm việc với dữ liệu latin-1 trong thiết bị đầu cuối UTF-8, hãy sử dụng luit(có trong bộ tiện ích X).

LC_CTYPE=en_US.iso88591 luit

(Bạn có thể sử dụng bất kỳ ngôn ngữ nào khác có cùng mã hóa, ví dụ LC_CTYPE=es_ES.iso88591 luit.)


Cảm ơn Gilles vì ​​lời giải thích tuyệt vời đó, đặc biệt là đã giải thích hai chỉ dẫn cho LC_CTYPE.
Craconia

Quay trở lại trường hợp cuối cùng của tôi: Tôi nghĩ rằng, vì tất cả các tên tệp được mã hóa bằng latin1 cộng với thực tế là thiết bị đầu ra cuối cùng của tôi, thiết bị tạo glyphs (thiết bị đầu cuối của tôi) cũng được định cấu hình cho latin1, tôi hy vọng sẽ thấy các tệp chính xác (bất kể LC_CTYPE) ...
Craconia

Tôi chưa bao giờ nghĩ rằng lsLC_CTYPE (được đặt thành UTF-8 trong trường hợp này) và sẽ thực hiện một số loại xác thực tập hợp ký tự: bất cứ khi nào thấy một cái gì đó không tương thích với bộ ký tự, nó sẽ nhổ một ký tự cụ thể (ví dụ: "? "). Tôi đã nói "xác nhận" vì nó sẽ không thực hiện "chuyển đổi" như luit. Có phải như thế này?
Craconia

@Craconia Trong trường hợp thứ ba, lsthay thế các ký tự không thể in bằng ?. Hầu hết các chuỗi được mã hóa theo tiếng Latin-1 đại diện cho các từ thực đều có các ký tự không thể in được nếu được hiểu là UTF-8.
Gilles 'SO- ngừng trở nên xấu xa'

5

Trong trường hợp # 2 và # 3, bạn đang trộn hai mã UTF-8 và Latin-1 khác nhau. Trong trường hợp # 1 bạn đang sử dụng Latin-1 cho cả hai, vì vậy bạn không gặp vấn đề gì.

Các lslệnh (và tất cả các chương trình dòng cũng hành xử khác) sử dụng cài đặt LANG để xác định mã hóa .

Bạn có thể trộn hai ngôn ngữ khác nhau, nhưng bạn không nên trộn hai bảng mã khác nhau .

Đảm bảo rằng các biến môi trường LC_ * cũng sử dụng cùng mã hóa với biến LANG của bạn.

Theo nguyên tắc thông thường, bạn nên cấu hình hệ thống của mình ngay bây giờ để chỉ sử dụng UTF-8.

Nếu bạn phải chỉnh sửa các tệp dữ liệu lỗi thời (ví dụ: thuộc tính java), bạn nên sử dụng trình chỉnh sửa chuyên dụng (ví dụ java ide) hoặc đảm bảo mã hóa bằng các công cụ như iconvhoặc `recode ..


Cảm ơn. Có, tôi có kế hoạch chuyển sang UTF-8 trong tương lai gần. Có một loạt tên tệp để chuyển đổi cộng với nhiều tệp văn bản. iconv & confmv để giải cứu ...
Craconia

0

Điều này có thể nằm ngoài nhu cầu của bạn, nhưng ....

Hóa ra trong RHEL5, và có lẽ trước đó, nhiều trang của người đàn ông có lý do nào đó đã bị bỏ qua vì lý do gd, đã bị đóng băng. Đó là, trang man thô đã được chuyển đổi từ ký tự gốc được đặt thành ASCII 7 bit. Bất kể bạn làm gì với LC và LANG, trang man để latin1tạo một trang man thực sự vô dụng. Tất cả các ký tự đặc biệt (8 bit) trong đã được thay thế bằng giữ chỗ 7 bit (thường ??). Tôi thấy điều này vui nhộn.

Nhưng utf8phiên bản của các trang man này có thể tồn tại trong thư mục dành riêng cho ngôn ngữ. Bí quyết là yêu cầu họ bằng đúng tên của họ. Ví dụ, latin1 là thực sự iso_8859-1. Nếu bạn thực hiện một trang hướng dẫn trên đó và cài đặt LANG của bạn là chính xác, bạn sẽ thấy những gì bạn mong đợi; trang man được tìm thấy trong thư mục con ngôn ngữ cụ thể ( en/man7/iso_8859-1.7). Nhưng nếu bạn yêu cầu iso-8859-1, vì một số lý do, bạn có được phiên bản ASCII.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.