Определите, сколько 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.

У меня проблемы с Google, потому что терминал и tty кажутся слишком общими терминами поиска. Самое большее, я приду к решениям, рекомендующим $TERMили tty.

Álex
источник

Ответы:

6

Ну, во-первых, я думаю, я бы хотел отметить, что почти все терминалы в наши дни "виртуальны" в том смысле, о котором вы говорите ... даже если терминал находится на другом конце настоящего последовательного порта. Я имею в виду, что времена 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 столбца, все хорошо.

Я уверен, что есть другие пробные символы, которые вы могли бы испустить, что привело бы к полезной информации. Я не знаю инструмент, который делает это автоматически.

Celada
источник
1
Спасибо за предложение, Селада. Однако, это не работает: я правильно вижу сообщенные продвинутые позиции (1 для é, 2 для あ). Разница лишь в том, что в XI я вижу реальные символы, а в tty1 я вижу ромб. Поэтому я думаю, что терминал действительно поддерживает utf-8, но ему не хватает символа в используемом шрифте.
Алекс
Я видел теперь команду showconsolefont. Это казалось возможным решением (с -v он сообщает, что шрифт 512-символьный). К сожалению, это работает только тогда, когда не используется Бёбу. В последнем случае возникает ошибка: «Не удалось получить дескриптор файла, ссылающийся на консоль». Если я явно передаю tty (опция -C), ошибка становится «Не удалось открыть / dev / pts / 37»
Álex
Между прочим: сценарий sh для определения конечной ширины строки (но это не тот вопрос, о котором идет речь)
Жиль "ТАК - перестань быть злым"
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является препятствием для моего варианта использования.
Алекс
Теперь это любопытно: setfontничего не выводит (не создает данный файл и не выдает ошибку) в виртуальных терминалах, но работает в реальных терминалах, как и ожидалось. Это в Ubuntu 16.04
Alex
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