ตรวจจับว่า Unicode เทอร์มินัลของฉันรองรับเท่าไรผ่านหน้าจอ


10

นี่คือปัญหา: ฉันต้องการที่จะแยกแยะว่าเทอร์มินัลของฉันมีความสามารถในการยูนิโค้ดได้หรือไม่เพื่อที่จะใช้ตัวละครบางตัวหรือไม่ก็เหมือนกับที่มองไม่เห็นซึ่งบางครั้งใช้สีและขีดเส้นใต้

แรงบันดาลใจเกิดขึ้นเพราะเทอร์มินัลเสมือนชนิดใดก็ได้ที่ฉันได้รับแบบอักษรที่ดี แต่ฉันเข้าใจว่าคอนโซล Linux พื้นฐานมีชุดอักขระเป็น 256 หรือ 512 สัญลักษณ์พร้อมกันดังนั้นคุณจึงไม่สามารถคาดหวังการสนับสนุนฟอนต์เต็มรูปแบบได้

ตอนแรกฉันคิดว่าฉันสามารถใช้$TERMหรือ tty ได้ แต่นี่ก็เป็นเรื่องที่จับได้: ฉันใช้ byobu ด้วยเช่นกันดังนั้นจึง$TERMเป็น "screen.linux" เสมอ ผลลัพธ์ของ tty ก็ไม่ได้บอกอะไรมาก: /dev/pts/<some number>ทั้งใน "ของจริง" และเงื่อนไขเสมือน

$BYOBU_TTYก็ไม่มีประโยชน์เช่นกันเพราะอาจเป็นเช่นนั้น/dev/tty1และเมื่อเปิดเซสชันในCtrl+ Alt+ F1อักขระจะไม่แสดง แต่เมื่อแนบกับเซสชันเดียวกันจากเทอม X บางรายการพวกเขาจะแสดงอย่างถูกต้องและยังคง$BYOBU_TTYไม่เปลี่ยนแปลง นอกจากนี้ฉันต้องการที่จะตรวจจับสิ่งนี้โดยไม่คิดว่า byobu อยู่ที่นั่นหรือไม่

นอกจากนี้โลแคลจะแสดงในทุกกรณี en_US.UTF-8

แต่อย่างใดสายตา (เพื่อชื่อเครื่องมือโดยเฉพาะอย่างยิ่งฉันเห็นการตรวจสอบนี้) แม้ใน byobu ใช้ผลลัพธ์ที่แตกต่างกันขึ้นอยู่กับ terminal ที่ฉันแนบกับเซสชัน byobu

ฉันมีปัญหากับ google เนื่องจากเทอร์มินัลและ tty ดูเหมือนข้อความค้นหาทั่วไปเกินไป อย่างมากฉันมาถึงวิธีการแก้ปัญหาที่แนะนำ$TERMหรือ tty

คำตอบ:


6

ก่อนอื่นฉันเดาว่าฉันจะชี้ให้เห็นว่าทุกวันนี้เทอร์มินัลทั้งหมดเป็น "เสมือน" ในแง่ที่คุณพูดถึง ... แม้ว่าเทอร์มินัลจะอยู่ที่ปลายอีกด้านหนึ่งของพอร์ตอนุกรม Bona fide ฉันหมายถึงวันของVT-100 s อาคารWyseและอาคาร "กายภาพ", "ของจริง" หายไปมาก!

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

แนวคิดคือการขอให้เครื่องบอกตำแหน่งเคอร์เซอร์ของคุณส่งออกอักขระทดสอบให้ถามเครื่องอีกครั้งเพื่อบอกตำแหน่งของคุณและเปรียบเทียบทั้งสองตำแหน่งเพื่อดูว่าเคอร์เซอร์ของเทอร์มินัลเคลื่อนไปไกลแค่ไหน

จะถามขั้วสำหรับตำแหน่งให้ดูที่นี่ เป็นหลัก:

echo -e "\033[6n"; read -d R foo; echo -en "\nCurrent position: "; echo $foo | cut -d \[ -f 2

ลองแสดงผล "é" อักขระนี้ใช้เวลา 2 ไบต์ใน UTF-8 แต่แสดงในคอลัมน์เดียวเท่านั้นบนหน้าจอ หากคุณตรวจพบว่าการส่งออก "é" ทำให้เคอร์เซอร์เคลื่อนที่ได้ 2 ตำแหน่งเทอร์มินัลก็ไม่รองรับ UTF-8 เลยและอาจมีขยะบางประเภท หากเคอร์เซอร์ไม่เคลื่อนที่เลยแสดงว่าเทอร์มินัลนั้นอาจเป็น ASCII เท่านั้น หากมันขยับไป 1 ตำแหน่งขอแสดงความยินดีก็อาจแสดงคำภาษาฝรั่งเศสได้

ลองแสดงผล "あ" อักขระนี้ใช้เวลา 3 ไบต์ใน UTF-8 แต่แสดงในสองคอลัมน์เท่านั้นบนหน้าจอ หากเคอร์เซอร์เคลื่อนที่ไปที่ 0 หรือ 3 ข่าวร้ายก็คล้ายกับด้านบน ถ้ามันเคลื่อนที่ทีละ 1 ดูเหมือนว่าเทอร์มินัลรองรับ UTF-8 แต่ไม่รู้เกี่ยวกับตัวอักษรแบบกว้าง (ในแบบอักษรที่มีความกว้างคงที่) ถ้ามันเคลื่อนที่ด้วย 2 คอลัมน์ทั้งหมดนั้นดี

ฉันแน่ใจว่ามีอักขระโพรบอื่น ๆ ที่คุณสามารถปล่อยซึ่งจะนำไปสู่ข้อมูลที่เป็นประโยชน์ ฉันไม่ได้ตระหนักถึงเครื่องมือที่ทำสิ่งนี้โดยอัตโนมัติ


1
ขอบคุณสำหรับคำแนะนำ Celada อย่างไรก็ตามมันใช้งานไม่ได้: ฉันเห็นรายงานตำแหน่งขั้นสูงอย่างถูกต้อง (1 สำหรับé, 2 สำหรับあ) ความแตกต่างเพียงอย่างเดียวคือภายใน XI เห็นตัวละครจริงในขณะที่อยู่ใน tty1 ฉันเห็นเพชร ดังนั้นฉันเดาว่าเทอร์มินัลรองรับ utf-8 จริงๆ แต่ขาดตัวอักษรในแบบอักษรที่ใช้
Álex

ฉันได้เห็นตอนนี้คำสั่ง showconsolefont นี่ดูเหมือนเป็นวิธีแก้ปัญหาที่เป็นไปได้ (ด้วย -v จะรายงานว่าแบบอักษรนั้นเป็นแบบ 512 ตัวอักษร) น่าเศร้าที่ใช้งานได้เฉพาะเมื่อไม่ได้ใช้ byobu ในกรณีสุดท้ายนี้มันเกิดข้อผิดพลาดกับ "ไม่สามารถรับไฟล์ descriptor ที่อ้างถึงคอนโซล" หากฉันผ่าน tty (ตัวเลือก -C) อย่างชัดเจนข้อผิดพลาดจะกลายเป็น "ไม่สามารถเปิด / dev / pts / 37"
Álex

โดยวิธีการ: สคริปต์การดวลจุดโทษในการกำหนดความกว้างของขั้วของสตริง ( แต่นั่นไม่ใช่สิ่งที่นี้คำถามที่เป็นเรื่องเกี่ยวกับ)
กิลส์ 'ทีเราหยุดเป็นคนชั่ว'

3

คำถามที่เกิดขึ้นจริงของ OP คือสิ่งที่ Unicode ค่าไม่สนับสนุนคอนโซล Linux screenและสามารถผู้ที่ถูกตรวจพบในขณะที่ทำงาน โดยหลักการแล้วเราสามารถทำได้โดยการดึงข้อมูลแผนที่ Unicode สำหรับคอนโซล

kbdแหล่งต้นไม้มีgetunimap(และหน้าคู่มือของมัน) หน้าคู่มือบอกว่า

โปรแกรม getunimap เก่าและล้าสมัย ตอนนี้มันเป็นส่วนหนึ่งของ setfont

ซึ่งไม่เป็นความจริงอย่างแน่นอน setfontมีตัวเลือกที่ไม่ประมาณในสิ่งเดียวกัน:

   -ou file                                  
          Save previous Unicode map in file

ความแตกต่าง:

  • setfontเขียนไปยังไฟล์ขณะที่getunimapเขียนไปยังเอาต์พุตมาตรฐาน
  • getunimap แสดงให้เห็นถึงตัวละครที่จะถูกแมปเป็นความคิดเห็น

ตัวอย่างเช่น:

0x0c4   U+2500  # ─ 
0x0c4   U+2501  # ━ 
0x0b3   U+2502  # │ 
0x0b3   U+2503  # ┃ 
0x0da   U+250c  # ┌ 
0x0da   U+250d  # ┍ 
0x0da   U+250e  # ┎ 
0x0da   U+250f  # ┏ 
0x0bf   U+2510  # ┐ 
0x0bf   U+2511  # ┑ 
0x0bf   U+2512  # ┒ 
0x0bf   U+2513  # ┓ 
0x0c0   U+2514  # └ 
0x0c0   U+2515  # ┕ 
0x0c0   U+2516  # ┖ 
0x0c0   U+2517  # ┗ 

กับ

0xc4    U+2500
0xc4    U+2501
0xb3    U+2502
0xb3    U+2503
0xda    U+250c
0xda    U+250d
0xda    U+250e
0xda    U+250f
0xbf    U+2510
0xbf    U+2511
0xbf    U+2512
0xbf    U+2513
0xc0    U+2514
0xc0    U+2515
0xc0    U+2516
0xc0    U+2517

หากคุณกำลังทำงานในscreen(หรือตัวอย่างเช่นการทำงานxtermและไม่ได้อยู่ในคอนโซล) คุณจะได้รับข้อผิดพลาดการอนุญาตที่คุณสามารถใช้งานsudoได้

หากฉันรู้ว่าตัวอักษรใดถูกโหลดฉันสามารถตรวจสอบว่า (ไม่มีสิทธิ์พิเศษ) โดยใช้psfgettableเช่น

zcat /usr/share/consolefonts/Lat2-Fixed16.psf.gz | psfgettable -

และดูข้อมูลการทำแผนที่ซึ่งsetfontจะใช้ในการโหลดแบบอักษร (ด้วยการทำแผนที่ Unicode):

#
# Character table extracted from font -
#
0x000   U+00a9
0x001   U+00ae
0x002   U+00dd
0x003   U+0104
0x004   U+2666 U+25c8 U+fffd
0x005   U+0105
0x006   U+0111
0x007   U+0150
0x008   U+0151
0x009   U+0162
0x00a   U+0164
0x00b   U+0170
0x00c   U+0171
0x00d   U+021a 
0x00e   U+02dd  
0x00f   U+2014 U+2015
0x010   U+2020
0x011   U+2021
0x012   U+2022 U+25cf
...

ทั้งสองgetunimapและsetfontให้ข้อมูลที่ไม่เรียงลำดับในขณะที่psfgettableดูเหมือนจะเรียงลำดับ (รวมถึงการรวมบรรทัดสำหรับค่า Unicode ที่แมปไปที่สัญลักษณ์เดียวกัน) ดังนั้นจึงมีความแตกต่าง แต่ข้อมูลสามารถเข้าถึงได้

อ่านเพิ่มเติม (แสดงเหตุผลที่คุณไม่สามารถใช้showconsolefontเพื่อแก้ไขปัญหานี้):


ขอบคุณโทมัสที่ทำให้คำถามเดิมของฉันชัดเจนขึ้นและทำให้ฉันถูกทาง ฉันจะพยายามดึงซับจากข้อมูลของคุณแล้วกลับมาพร้อมผลลัพธ์ การใช้sudoไม่มีอุปสรรคสำหรับกรณีการใช้ของฉัน
Álex

ตอนนี้สิ่งที่อยากรู้คือsetfontเอาท์พุทอะไร (ไม่สร้างไฟล์ที่กำหนดหรือส่งออกข้อผิดพลาด) ภายในเทอร์มินัลเสมือน แต่ทำงานในเทอร์มินัลจริงตามที่คาดไว้ นี่คือใน Ubuntu 16.04
Álex

2

ฉันเจอคำถามนี้ขณะที่พยายามทำสิ่งเดียวกัน แต่ไม่ต้องการทิ้งอะไรไว้บนหน้าจอและตั้งค่าตัวแปรดังนั้นฉันจึงใส่คำสั่งต่อไปนี้ลงในเชลล์สคริปต์ที่ฉันใช้:

function test_unicode {
  echo -ne "\xe2\x88\xb4\033[6n\033[1K\r"
  read -d R foo
  echo -ne "\033[1K\r"
  echo -e "${foo}" | cut -d \[ -f 2 | cut -d";" -f 2 | (
    read UNICODE
    [ $UNICODE -eq 2 ] && return 0
    [ $UNICODE -ne 2 ] && return 1
  )
}

test_unicode
RC=$?
export UNICODE_SUPPORT=`[ $RC -eq 0 ] && echo "Y" || echo "N"`
unset test_unicode

1
ขอบคุณสำหรับการบริจาคเจฟ น่าเศร้าที่ฉันได้รับ Y เสมอแม้ในคอนโซลพื้นฐาน: S
Álex
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.