ผลกระทบของ $ LANG บนเทอร์มินัล


11

ฉันพยายามที่จะเรียนรู้ว่า$LANGตัวแปรทำงานอย่างไรกับ gnome-terminal (และตัวเลือกการตั้งค่าการเข้ารหัสอักขระ) ฉันใช้ iso8859-1 (latin1) เป็นตัวละครหลักของฉันและชื่อไฟล์ทั้งหมดของฉันถูกเข้ารหัสเช่นนี้

สำหรับการทดสอบต่อไปนี้ฉันจะทำls -lไดเรกทอรีที่มีอักขระเน้นเสียงภาษาสเปนในชื่อไฟล์ของพวกเขา:

กรณี # 1:

  • gnome-terminal ที่กำหนดค่าไว้สำหรับ ISO-8859-1
  • LANG ตั้งค่าเป็น "en_US-iso8859-1"
  • ผลลัพธ์: ฉันเห็นไฟล์ทั้งหมดอย่างถูกต้อง

กรณีที่ 2:

  • gnome-terminal กำหนดค่าสำหรับ UTF-8
  • LANG ตั้งค่าเป็น "en_US-iso8859-1"
  • ผลลัพธ์: ฉันเห็นอักขระขยะสำหรับอักขระภาษาสเปนทั้งหมด สิ่งนี้คาดว่าจะเกิดขึ้นเมื่อฉันเปลี่ยนการเข้ารหัสอักขระสำหรับเทอร์มินัล

กรณี # 3:

  • gnome-terminal ที่กำหนดค่าไว้สำหรับ ISO-8859-1
  • LANG ตั้งค่าเป็น "en_US-UTF-8"
  • ผลลัพธ์: ฉันเห็นอักขระขยะสำหรับอักขระภาษาสเปนทั้งหมด

ทำไมในกรณีนี้ฉันเห็นตัวอักษรที่อ่านไม่ออก ผลลัพธ์ของlsไม่ควรส่งชื่อไฟล์ไปยัง gnome-terminal อย่างที่เป็นหรือ และเนื่องจาก gnome-terminal ได้รับการกำหนดค่าสำหรับ ISO-8859-1 ฉันจึงคาดว่าพวกมันจะถูกต้อง

สักครู่ฉันคิดว่าบางทีบางที bash กำลังพิจารณา$LANGตัวแปรของฉันและทำการแปลงบางอย่าง จากนั้นฉันเปลี่ยนเทอร์มินัลเป็น UTF-8 แต่ฉันยังไม่เห็นอักขระ ฉันได้ส่งออก ls ไปยัง xxd และทำให้ฉันประหลาดใจฉันยังเห็นไฟล์ที่เข้ารหัสตามที่เป็นอยู่: ISO-8859-1

ในการสรุป: หากรายชื่อของฉันมีอักขระ ISO-8859-1 และตัวจำลองเทอร์มินัลของฉันได้รับการกำหนดค่าสำหรับการเข้ารหัสอักขระเดียวกัน: ใครกำลังทำการแปลงเมื่อLANGตั้งค่าไว้เป็นอย่างอื่น

ขอบคุณสำหรับความช่วยเหลือที่คุณสามารถให้ได้

Craconia

คำตอบ:


5

การตั้งค่าของคุณสำหรับLANGจะต้องตรงกับขั้ว แม่นยำยิ่งขึ้นการตั้งค่าของคุณสำหรับLC_CTYPE(การเข้ารหัสอักขระ) จะต้องตรงกับการเข้ารหัสของเทอร์มินัลการตั้งค่าโลแคลอื่น ๆ ไม่จำเป็นต้องตรงกัน และการเข้ารหัสของเทอร์มินัลมักจะถูกระบุโดยตัวเลือกของเทอร์มินัลอีมูเลเตอร์และไม่ใช้ตัวแปรโลแคล การLC_CTYPEรวมสองตัวบ่งชี้: มันบอกแอปพลิเคชันว่าการเข้ารหัสที่จะใช้บนเทอร์มินัล (ทั้งสำหรับอินพุตและเอาต์พุต) และมันบอกแอปพลิเคชันว่าการเข้ารหัสที่จะใช้กับไฟล์ ในกรณีที่ 2 และ 3 คุณได้บอกlsให้แสดงเอาต์พุตในการเข้ารหัสที่แตกต่างจากเทอร์มินัลดังนั้นเอาต์พุตจะอ่านไม่ออก

หากคุณทำงานกับการเข้ารหัส UTF-8 และ latin-1 ในเวลาที่ต่างกันให้กำหนดค่าเทอร์มินัลของคุณให้ใช้ UTF-8 สิ่งนี้ควรทำให้ตั้งค่าLC_CTYPEเป็นค่าที่ระบุ UTF-8 อย่าแทนที่การตั้งค่านี้ (หากเทอร์มินัลอีมูเลเตอร์ไม่ได้ตั้งค่าLC_CTYPEให้ทำการแทนที่ในไฟล์เริ่มต้นเชลล์หรือสำหรับเซสชันทั้งหมดของคุณ) เพื่อทำงานกับข้อมูล latin-1 ในเทอร์มินัล UTF-8 ให้ใช้luit(รวมอยู่ในชุดยูทิลิตี้ X)

LC_CTYPE=en_US.iso88591 luit

(คุณสามารถใช้ภาษาอื่นใดก็ได้ด้วยการเข้ารหัสเดียวกันLC_CTYPE=es_ES.iso88591 luit)


ขอบคุณ Gilles สำหรับคำอธิบายที่ยอดเยี่ยมโดยเฉพาะอย่างยิ่งสำหรับการอธิบายสองสิ่งบ่งชี้สำหรับ LC_CTYPE
Craconia

กลับไปที่กรณีสุดท้ายของฉัน: ฉันคิดว่าเนื่องจากชื่อไฟล์ทั้งหมดถูกเข้ารหัสใน latin1 บวกกับความจริงที่ว่าอุปกรณ์ส่งออกสุดท้ายของฉันคนที่สร้าง glyphs (เทอร์มินัลของฉัน) ได้รับการกำหนดค่าสำหรับ latin1 ด้วย (โดยไม่คำนึงถึง LC_CTYPE) ...
Craconia

มันไม่เคยเกิดขึ้นกับฉันที่lsจะพิจารณา LC_CTYPE (ตั้งค่าเป็น UTF-8 ในกรณีนี้) และจะทำการตรวจสอบชุดอักขระบางชนิด: เมื่อใดก็ตามที่เห็นสิ่งที่ไม่เข้ากันกับชุดอักขระมันจะคายอักขระเฉพาะ (เช่น "? ") ฉันพูดว่า "การตรวจสอบความถูกต้อง" เพราะมันจะไม่ทำการ "แปลง" เท่าที่จะทำได้ เป็นเช่นนี้หรือไม่?
Craconia

@Craconia ในกรณีที่สามlsแทนที่อักขระที่ไม่สามารถพิมพ์?ได้ สตริงส่วนใหญ่ที่เข้ารหัสใน latin-1 ที่แสดงถึงคำศัพท์จริงมีอักขระที่ไม่สามารถพิมพ์ได้หากตีความว่าเป็น UTF-8
Gilles 'หยุดความชั่วร้าย'

5

ในกรณีที่ # 2 และ # 3 คุณกำลังผสมการเข้ารหัส UTF-8 ที่แตกต่างกันสองแบบและละติน -1 ในกรณีที่ # 1 คุณใช้ละติน -1 ทั้งคู่ดังนั้นคุณจึงไม่มีปัญหา

lsคำสั่ง (และ programms ดีพฤติกรรมอื่น ๆ ) ใช้การตั้งค่าภาษาในการพิจารณาการเข้ารหัส

คุณอาจจะผสมสองภาษาที่แตกต่างกัน แต่คุณไม่ควรผสมสองการเข้ารหัสที่แตกต่างกัน

ตรวจสอบให้แน่ใจว่าตัวแปรสภาพแวดล้อม LC_ * นั้นใช้การเข้ารหัสเช่นเดียวกับตัวแปร LANG ของคุณ

ตามกฎทั่วไปคุณควรกำหนดค่าระบบของคุณทุกวันนี้ให้ใช้เฉพาะ UTF-8

หากคุณต้องแก้ไขไฟล์ข้อมูลแบบเก่า (เช่นคุณสมบัติของจาวา) คุณควรใช้เครื่องมือแก้ไขพิเศษ (เช่นจาวา IDE) หรือตรวจสอบให้แน่ใจว่าการเข้ารหัสด้วยเครื่องมือเช่นiconvหรือ `recode ..


ขอบคุณ ใช่ฉันมีแผนที่จะเปลี่ยนเป็น UTF-8 ในอนาคตอันใกล้ มีชื่อไฟล์มากมายให้แปลงรวมถึงไฟล์ข้อความจำนวนมาก iconv & convmv เพื่อช่วยเหลือ ...
Craconia

0

นี่อาจเป็นสิ่งที่คุณต้องการ แต่ ....

มันปรากฎใน RHEL5 และอาจก่อนหน้านี้หลายหน้ามีเหตุผลบางอย่างสำหรับเหตุผลบางอย่างที่ถูกลืม นั่นคือหน้าคนดิบได้รับการแปลงจากตัวละครพื้นเมืองของมันถูกตั้งค่าเป็น 7 บิต ASCII ไม่ว่าคุณจะทำอะไรกับ LC และ LANG หน้า man สำหรับlatin1สร้าง man page ที่ไร้ประโยชน์อย่างมีประสิทธิภาพ อักขระพิเศษทั้งหมด (8 บิต) ภายในถูกแทนที่ด้วยตัวยึด 7 บิต (ปกติ??) ฉันพบว่าเฮฮานี้

แต่utf8เวอร์ชันของ man page เหล่านี้อาจมีอยู่ในไดเรกทอรีเฉพาะภาษา เคล็ดลับคือการขอชื่อที่ถูกต้อง ยกตัวอย่างเช่น latin1 iso_8859-1เป็นจริง หากคุณทำ man page ไว้และการตั้งค่า LANG ของคุณถูกต้องคุณจะเห็นสิ่งที่คุณคาดหวัง พบ man page ในส่วนย่อยเฉพาะภาษา ( en/man7/iso_8859-1.7) แต่ถ้าคุณถามiso-8859-1ด้วยเหตุผลบางอย่างคุณจะได้รับเวอร์ชัน ASCII

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.