Mendeteksi berapa banyak Unicode yang didukung terminal saya, bahkan melalui layar

10

Inilah masalahnya: Saya ingin dapat melihat apakah terminal saya mampu unicode yang layak atau tidak, untuk menggunakan beberapa karakter atau tidak, seperti halnya sekilas, yang kadang-kadang menggunakan warna dan yang lainnya menggarisbawahi.

Motivasi muncul karena dalam segala jenis terminal virtual saya mendapatkan font yang layak, tetapi saya mengerti bahwa konsol Linux dasar memiliki seperangkat karakter 256 atau 512 simbol simultan, sehingga Anda tidak dapat mengharapkan dukungan font penuh.

Pada awalnya saya berpikir bahwa saya bisa menggunakan $TERMatau tty, tapi inilah masalahnya: Saya menggunakan byobu juga, jadi $TERMselalu "screen.linux". Output dari tty juga tidak terlalu jitu: /dev/pts/<some number>dalam istilah "nyata" dan virtual.

$BYOBU_TTYjuga tidak membantu, karena misalnya mungkin /dev/tty1dan ketika sesi dibuka di Ctrl+ Alt+ F1karakter tidak muncul tetapi ketika melampirkan sesi yang sama dari beberapa istilah X, mereka tampil dengan baik dan masih $BYOBU_TTYtidak berubah. Selain itu, saya ingin dapat mendeteksi ini tanpa menganggap byobu ada atau tidak.

Selain itu, lokal menunjukkan dalam semua kasus en_US.UTF-8

Namun entah bagaimana melirik (untuk memberi nama alat tertentu yang saya lihat mendeteksi ini), bahkan di dalam byobu, menggunakan output yang berbeda tergantung pada terminal yang saya lampirkan pada sesi byobu.

Saya mengalami masalah dengan google karena terminal dan tty tampaknya istilah pencarian yang terlalu umum. Paling-paling saya tiba di solusi merekomendasikan $TERMatau tty.

Álex
sumber

Jawaban:

6

Yah, pertama saya kira saya akan menunjukkan bahwa hampir semua terminal hari ini adalah "virtual" dalam arti yang Anda bicarakan ... bahkan jika terminal berada di ujung port serial yang bonafid. Maksudku, hari-hari VT-100 , terminal Wyse dan terminal "fisik", "nyata" lainnya sudah hampir berlalu!

Selain itu, katakanlah Anda ingin mendeteksi jenis dukungan Unicode yang dimiliki terminal Anda. Anda dapat melakukan ini dengan menulis karakter uji dan melihat apa yang terjadi. (Anda dapat berupaya menghapus karakter uji setelah Anda menulisnya, tetapi pengguna mungkin masih melihatnya sebentar, atau menghapusnya mungkin tidak berfungsi dengan baik sejak awal.)

Idenya adalah meminta terminal untuk memberi tahu Anda posisi kursornya, mengeluarkan karakter uji, meminta terminal lagi untuk memberi tahu Anda posisinya, dan membandingkan dua posisi untuk melihat seberapa jauh kursor terminal bergerak.

Untuk menanyakan posisi terminal, lihat di sini . Pada dasarnya:

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

Coba keluarankan "é". Karakter ini membutuhkan 2 byte dalam UTF-8 tetapi hanya menampilkan satu kolom di layar. Jika Anda mendeteksi bahwa mengeluarkan "é" menyebabkan kursor bergerak dengan 2 posisi, maka terminal tidak memiliki dukungan UTF-8 sama sekali dan mungkin menghasilkan semacam sampah. Jika kursor tidak bergerak sama sekali, maka terminal mungkin hanya ASCII. Jika dipindahkan dengan 1 posisi, maka selamat, itu mungkin dapat menampilkan kata-kata Prancis.

Coba keluaran "あ". Karakter ini membutuhkan 3 byte dalam UTF-8 tetapi hanya menampilkan dua kolom di layar. Jika kursor bergerak 0 atau 3, berita buruk, mirip dengan di atas. Jika bergerak 1, maka sepertinya terminal mendukung UTF-8 tetapi tidak tahu tentang karakter lebar (dalam font lebar-tetap). Jika bergerak 2 kolom, semuanya baik-baik saja.

Saya yakin ada karakter probe lain yang dapat Anda pancarkan yang akan menghasilkan informasi yang bermanfaat. Saya tidak mengetahui alat yang melakukan ini secara otomatis.

Celada
sumber
1
Terima kasih atas sarannya, Celada. Namun, itu tidak berfungsi: Saya benar melihat melaporkan posisi-posisi maju (1 untuk é, 2 untuk あ). Satu-satunya perbedaan adalah bahwa di dalam XI melihat karakter asli sementara di tty1 saya melihat berlian. Jadi saya kira terminal benar-benar mendukung utf-8, tetapi tidak memiliki karakter dalam font yang digunakan.
Álex
Saya telah melihat sekarang perintah showconsolefont. Ini sepertinya solusi yang mungkin (dengan -v melaporkan font-nya adalah 512-charset). Sayangnya, ini hanya berfungsi ketika tidak menggunakan byobu. Dalam kasus terakhir ini, itu salah dengan "Tidak bisa mendapatkan deskriptor file yang merujuk ke konsol". Jika saya secara eksplisit melewati tty (opsi -C), kesalahan menjadi "Tidak dapat membuka / dev / pts / 37"
Álex
Ngomong-ngomong: skrip untuk menentukan lebar terminal string (tapi bukan itu pertanyaannya)
Gilles 'SO- stop being evil'
3

Pertanyaan aktual OP adalah: apa nilai-nilai Unicode yang didukung oleh konsol Linux, dan dapatkah itu terdeteksi saat dijalankan screen. Pada prinsipnya, orang dapat melakukan ini dengan mengambil peta Unicode untuk konsol.

The kbdsource mengandung getunimap(dan halaman manualnya). Halaman manual mengatakan itu

Program getunimap sudah tua dan usang. Sekarang bagian dari setfont

yang tidak sepenuhnya benar. setfontmemiliki opsi yang kira - kira melakukan hal yang sama:

   -ou file                                  
          Save previous Unicode map in file

Perbedaan:

  • setfontmenulis ke file, sementara getunimapmenulis ke output standar
  • getunimap menunjukkan karakter yang akan dipetakan, sebagai komentar.

Sebagai contoh:

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  # ┗ 

melawan

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

Jika Anda menjalankan screen(atau misalnya berjalan xtermdan tidak di konsol), Anda akan mendapatkan kesalahan izin yang bisa Anda selesaikan sudo.

Jika saya mengetahui font mana yang dimuat, saya dapat memeriksanya (tanpa izin khusus) menggunakan psfgettable, misalnya,

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

dan lihat data pemetaan yang setfontakan digunakan untuk memuat font (dengan pemetaan 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
...

Keduanya getunimapdan setfontmemberikan data yang tidak disortir, sementara psfgettabletampaknya disortir (serta menggabungkan garis untuk nilai Unicode yang memetakan ke mesin terbang yang sama). Jadi ada perbedaan, tetapi informasinya dapat diakses.

Bacaan lebih lanjut (menggambarkan mengapa Anda tidak dapat menggunakan showconsolefontuntuk memecahkan masalah ini):

Thomas Dickey
sumber
Terima kasih, Thomas, karena telah mengklarifikasi pertanyaan awal saya dan menempatkan saya di jalur yang benar. Saya akan mencoba untuk mendapatkan satu-liner sederhana dari informasi Anda dan kembali dengan hasilnya. Menggunakan sudobukanlah halangan untuk use case saya.
Álex
Sekarang, ini aneh: setfonttidak menghasilkan apa-apa (tidak membuat file yang diberikan atau menghasilkan kesalahan) dalam terminal virtual, tetapi bekerja di terminal aktual seperti yang diharapkan. Ini ada di Ubuntu 16.04
Álex
2

Saya menemukan pertanyaan ini ketika saya mencoba untuk mencapai hal yang sama, tetapi tidak ingin meninggalkan apa pun di layar dan mengatur variabel, jadi saya memasukkan yang berikut ini dalam skrip shell yang saya sumber:

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
Jeff
sumber
1
Terima kasih atas kontribusinya, Jeff. Sayangnya saya selalu Y bahkan di konsol dasar: S
Álex