Linux – Detect how much of Unicode the terminal supports, even through screen

linuxterminalttyunicode

Here's the problem: I want to be able to discern if my terminal is capable of decent unicode or not, in order to use some characters or not, much like glances does, that sometimes uses colors and others underline.

The motivation arises because in any kind of virtual terminal I get decent fonts, but I understand that the basic Linux console has a character set of 256 or 512 simultaneous symbols, so you cannot expect full font support.

At first I thought that I could use $TERM or tty, but here's the catch: I'm using byobu too, so $TERM is always "screen.linux". The output of tty is also not very telling: /dev/pts/<some number> in both "real" and virtual terms.

$BYOBU_TTY is no help either, because e.g. it may be /dev/tty1 and when the session is opened in Ctrl+Alt+F1 the characters don't show but when attaching to the same session from some X term, they show properly and still $BYOBU_TTY does not change. Besides, I'd like to be able to detect this without presuming byobu is there or not.

Also, locale shows in all cases en_US.UTF-8

Yet somehow glances (to name a particular tool I see detecting this), even inside byobu, uses different output depending on the terminal I'm attaching to the byobu session.

I'm having trouble with google because terminal and tty seem too common search terms. At most I arrive at solutions recommending $TERM or tty.

Best Answer

Well, first I guess I would point out that pretty much all terminals these days are "virtual" in the sense you talk about... even if the terminal is at the other end of a bona fide serial port. I mean, the days of VT-100s, Wyse terminals and other "physical", "real" terminals are pretty much gone!

That aside, let's say you want to detect what kind of Unicode support your terminal has. You can do this by writing test characters to is and seeing what happens. (You can make an effort to erase the test characters after you've written then, but the user may still see them briefly, or erasing them might not work properly in the first place.)

The idea is to ask the terminal to tell you its cursor position, output a test character, ask the terminal again to tell you its position, and compare the two positions to see how far the terminal's cursor moved.

To ask the terminal for its position, see here. Essentially:

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

Try outputting "é". This character takes 2 bytes in UTF-8 but displays in only one column on the screen. If you detect that outputting "é" causes the cursor to move by 2 positions, then the terminal has no UTF-8 support at all and has probably output some kind of garbage. If the cursor didn't move at all, then then terminal is probably ASCII only. If it moved by 1 position, then congratulations, it can probably display French words.

Try outputing "あ". This character takes 3 bytes in UTF-8 but displays in only two columns on the screen. If the cursor moves by 0 or 3, bad news, similar to above. If it moves by 1, then it looks like the terminal supports UTF-8 but doesn't know about wide characters (in fixed-width fonts). If it moves by 2 columns, all is good.

I'm sure there are other probe characters that you could emit which would lead to useful information. I am not aware of a tool that does this automatically.

Related Question