画面でも、端末がサポートする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変更されないためです。その上、屏風があるかどうかを推定せずにこれを検出できるようにしたいと思います。

また、ロケールはすべての場合にen_US.UTF-8を示します

それでも、byobuの内部であっても、どういうわけか(私がこれを検出した特定のツールの名前を示すために)一見すると、byobuセッションに接続している端末に応じて異なる出力が使用されます。

端末とttyがあまりにも一般的な検索語のように見えるため、Googleで問題が発生しています。せいぜい$TERMttyを推奨するソリューションにたどり着きます。

回答:


6

さて、最初に、最近のほとんどすべての端末は、あなたが話している意味で「仮想」であると指摘します...端末が真正なシリアルポートの反対側にある場合でもです。つまり、VT-100Wyse端末、その他の「物理的」で「実際の」端末の時代はほとんどなくなっています。

それはさておき、端末がどのようなUnicodeサポートをサポートしているかを検出したいとしましょう。これを行うには、テスト文字をisに書き込み、何が起こるかを確認します。(その時点で書き込んだ後、テスト文字を消去するように努力することはできますが、ユーザーがそれらを一瞬表示するか、最初から正しく消去できない可能性があります。)

端末にカーソルの位置を教えてもらい、テスト文字を出力し、もう一度端末に位置を教えてもらい、2つの位置を比較して端末のカーソルの移動距離を確認するという考え方です。

端末にその位置を尋ねるには、こちらを参照してください。基本的に:

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

「é」を出力してみてください。この文字は、UTF-8では2バイトを使用しますが、画面の1つの列にのみ表示されます。「é」を出力するとカーソルが2ポジション移動することが検出された場合、端末はUTF-8をまったくサポートしておらず、おそらく何らかのガベージを出力しています。カーソルがまったく動かなかった場合、端末はおそらくASCIIのみです。1ポジション移動した場合、おめでとうございます。おそらくフランス語の単語を表示できます。

「あ」を出力してみてください。この文字は、UTF-8では3バイトを使用しますが、画面の2つの列にのみ表示されます。カーソルが0または3移動した場合、上記と同様に悪いニュースです。1ずつ移動する場合、端末はUTF-8をサポートしているように見えますが、(固定幅フォントの)ワイド文字については認識していません。2桁移動すれば全て良好です。

役立つ情報につながる、他のプローブキャラクターが出てくると思います。これを自動的に行うツールについては知りません。


1
提案をありがとう、Celada。ただし、機能していません。レポートされたポジションが進んだと正しく表示されます(éは1、あは2)。唯一の違いは、XI内では実際の文字が表示されるのに対し、tty1ではダイヤモンドが表示されることです。そのため、ターミナルは実際にはutf-8をサポートしていますが、使用されているフォントの文字が不足していると思います。
アレックス

コマンドshowconsolefontを見てきました。これは可能な解決策のように思われました(-vを指定すると、フォントが512文字セットであると報告されます)。残念ながら、byobuを使用しない場合にのみ機能します。この最後のケースでは、「コンソールを参照するファイル記述子を取得できませんでした」というエラーが発生します。私は明示的にttyの(-Cオプション)を渡すと、エラーが「は/ dev / PTS / 37を開くことができませんでした」となり
アレックス・

ちなみに、文字列の終端幅を決定するshスクリプト(ただし、この質問についてはそうではありません)
Gilles 'SO- stop be evil'

3

OPの実際の質問は次のとおりです。LinuxコンソールがサポートするUnicode値は何ですか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
...

双方getunimapsetfontしながら、ソートされていないデータを与えるpsfgettable現れるが(ユニコード値の線を組み合わせ、並びにそのマップ同じグリフに)ソートします。したがって、違いはありますが、情報にはアクセスできます。

さらに読む(なぜshowconsolefontこの問題を解決するために使用できないのかを示す):


トーマス、元の質問を明確にして正しい軌道に乗せてくれてありがとう。私はあなたの情報から簡単なワンライナーを取得して、結果を返すようにします。使用することsudoは、私のユースケースにとって障害にはなりません。
アレックス

さて、これは奇妙です:setfont仮想端末内では何も出力しません(与えられたファイルを作成せず、エラーも出力しません)が、実際の端末では期待どおりに動作します。これは、Ubuntuの16.04である
アレックス

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
貢献してくれてありがとう、ジェフ。S:悲しいことに私も基本的なコンソールに常にYを得る
アレックス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.