В. Костромин (kos at rus-linux dot net), "11.3. Русификация консоли" - 14/09/2004 || Библиотека ЛинуксЦентра

Глава 11. Русификация и шрифты

Предыдущий раздел Оглавление Следующий раздел

11.3. Русификация консоли

11.3.1. Что нужно сделать

Если вы внимательно прочитали разд. 9.3 и разд. 11.1, то представляете, что для русификации консоли (а консоль - это, грубо говоря, совокупность клавиатуры и дисплея) требуется загрузить в драйвер консоли три таблицы:

Таблицы раскладки клавиатуры находятся в каталоге /usr/lib/kbd/keymaps/i386/qwerty. Выбор конкретного файла раскладки задается файлом /etc/sysconfig/keyboard. Этот файл можно отрегулировать вручную, а можно с помощью программы kbdconfig. В последнем случае нужная таблица с раскладкой клавиатуры загружается в память. При ручном изменении файла /etc/sysconfig/keyboard перезагрузка таблицы произойдет только после перезапуска компьютера или после выполнения команды (в примере загружается раскладка из файла ru-win.map):

[root]# loadkeys /usr/lib/kbd/keymaps/i386/qwerty/ru-win.map

Второй шаг русификации состоит в задании и загрузке таблицы экранного шрифта (SFM) в драйвер дисплея. Эти таблицы хранятся в виде файлов в каталоге /usr/lib/kbd/consolefonts. Загрузка шрифтов осуществляется немного по-разному в пакетах kbd и consoletools (соответственно, в версиях 5.2 и 6.x Red Hat Linux). В версии 5.2 загрузка шрифта осуществлялась с помощью команды setfont. Например, чтобы загрузить кодовую страницу из файла Cyr_a8x16, нужно дать команду

[root]# setfont /usr/lib/kbd/consolefonts/Cyr_a8x16

В версии 6.0 и последующих надо использовать команду consolechars с опцией -f:

[root]# consolechars -f /usr/lib/kbd/consolefonts/Cyr_a8x16

(Отметим, что команда setfont тоже сработает, только выдаст предупреждение о том, что надо пользоваться командой consolechars.)

Файлы шрифтов являются бинарными файлами размером 256*H байт, содержащими битовые образы для каждого из 256 символов, по одному байту на каждую линию образа и по H байт на символ (0 < H <= 32). В этом случае о размере шрифта по вертикали можно судить по длине файла. В качестве файлов шрифтов могут использоваться файлы .psf; они имеют тот же самый формат и, кроме того, заголовок размером 4 байта. Некоторые файлы шрифтов содержат сразу три шрифта разного размера (например, 8х8, 8х14, 8х16), тогда в команде consolechars надо добавить опцию -H, например: -H 16, для выбора одного из размеров. Поскольку ядро Linux не поддерживает пока переключение режимов работы экрана, consolechars (как и setfont) не может изменить текущий режим EGA/VGA. Таким образом, пользователь полностью ответственен за выбор шрифта, соответствующего текущему режиму экрана.

Соответствие между символами кода ASCII и образами (или изображениями символов) из файла шрифта можно изменить, используя таблицу перекодировки (ACM - Application Charset Map). Если эту таблицу не загрузить, то, например, в программе Midnight Commander вы можете вместо красивых рамочек увидеть столбцы и строки из непонятных символов. Некоторые файлы шрифтов включают таблицу перекодировки шрифта, и тогда consolechars загрузит эту таблицу. По умолчанию файлы шрифтов находятся в каталоге /usr/lib/kbd/consolefonts, а таблицы перекодировки - в каталоге /usr/lib/kbd/consoletrans.

Таблицу перекодировки в 6-ой версии Red Hat (т. е. в пакете consoletools) можно загрузить отдельной командой consolechars с опцией -m file:

[root]# consolechars -m /usr/lib/kbd/consoletrans/koi2alt

Если таблица перекодировки не включена в файл шрифта и не указана в опции -m, то используется "тривиальная" таблица.

В версии 5.2 для загрузки таблицы перекодировки используется команда mapscrn:

[root]# mapscrn /usr/lib/kbd/consoletrans/koi2alt.

В этом случае драйвер консоли должен быть дополнительно переведен в режим перекодировки, задаваемый таблицей, путем вывода на консоль специальной escape-последовательности. Эта последовательность есть <esc>(K для набора символов G0 (G0 character set) и <esc>)K для набора символов G1 (G1 character set). Заметим, что активизировать эту таблицу необходимо в каждой консоли. При этом команда loadkeys действует одновременно во всех виртуальных консолях, а вот команда mapscrn действует только в той виртуальной консоли, в которой выполнена команда echo -ne '\033(K'.

Замечание:

Esc(K требуется, когда загружается альтернативная кодировка и активизируется таблица перекодировки псевдографики командой mapscrn koi2alt. Если шрифт koi-8, то никаких Esc(K не надо.

Замечание:

Все это не действует из-под Midnight Commander!

Существует еще таблица перекодировки для символов UNICODE. Некоторые файлы шрифтов включают эту таблицу, и она будет загружена командой consolechars, если только не задана опция --force-no-sfm. Отдельно загрузить таблицу перекодировки символов Unicode можно командой consolechars с опцией -u (см. руководство man).

Итак, для того, чтобы русифицировать консоль, нужно выполнить следующую последовательность команд:

loadkeys /usr/lib/kbd/keytables/i386/qwerty/ru.map

setfont /usr/lib/kbd/consolefonts/Cyr_a8x16

mapscrn /usr/lib/kbd/consoletrans/koi2alt

echo -ne '\033(K'

loadkeys /usr/lib/kbd/keytables/i386/qwerty/ru.map

consolechars -f /usr/lib/kbd/consolefonts/Cyr_a8x16

consolechars -m /usr/lib/kbd/consoletrans/koi2alt

Но выполнять эту последовательность команд после каждого перезапуска компьютера, да еще в каждой виртуальной консоли, слишком обременительно. Поэтому рассмотрим вкратце, как русификация выполняется в дистрибутиве Black Cat Linux.

11.3.2 Как это сделано в дистрибутиве Black Cat

Во-первых, в файле /etc/sysconfig/i18n вводится новая переменная: в версии 5.2 это переменная SCRNMAP, а в версии 6.02 - SYSFONTACM. Этой переменной по умолчанию присваивается значение "koi2alt". Вот стандартный файл i18n из Black Cat Linux версии 6.02:

LANG=ru

LINGUAS=ru

LC_ALL=ru_RU.KOI8-R

SYSFONT=RUSCII_8x16

SYSFONTACM=koi2alt

Вызов файла i18n для задания значений переменных осуществляется из скрипта /sbin/setsysfont, из которого вызываются также команды setfont и mapscrn (в версии 5.2) или consolechars (в версии 6.0). Вот этот скрипт из Black Cat Linux версии 5.2:

-----------------------------------
#!/bin/sh
if [ -f /etc/sysconfig/i18n ]; then
            . /etc/sysconfig/i18n
fi
if [ -x /usr/bin/setfont ]; then
       if [ -n "$SYSFONT" ]; then
		/usr/bin/setfont $SYSFONT
	fi
if [ -x /usr/bin/mapscrn ]; then
	if [ -n "$SCRNMAP" ]; then
		/usr/bin/mapscrn $SCRNMAP
	fi
fi
else
	echo "can't set font"
	exit 1
fi
------------------------------------

Как видно, при вызова скрипта /sbin/setsysfont выполняются команды "setfont Cyr_a8x16" и "mapscrn koi2alt". После этого, для включения в ядре кодовой таблицы пользователя, необходимо выдать на каждую виртуальную консоль последовательность "\033(K". Это реализовано путем добавления этой последовательности к файлу /etc/issue, который генерируется при загрузке системы скриптом /etc/rc.d/rc.local и вызывается на исполнение при логировании каждого пользователя. Вот пример скрипта /etc/rc.d/rc.local из версии 5.2:

-------------------------------------
#!/bin/sh
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.
if [ -f /etc/blackcat-release ]; then
        R=$(cat /etc/blackcat-release)
elif [ -f /etc/redhat-release ]; then
	R=$(cat /etc/redhat-release)
else
    R="release 3.0.3"
fi
arch=$(uname -m)
a="a"
case "_$arch" in
_a*) a="an";;
_i*) a="an";;
esac
# This will overwrite /etc/issue at every boot. So, make any changes you
# want to make to /etc/issue here or you will lose them when you reboot.
. /etc/sysconfig/i18n
echo "" > /etc/issue.net
echo "Black Cat Linux $R" >> /etc/issue.net
echo "Kernel $(uname -r) on $a $(uname -m)" >> /etc/issue.net
if [ -n "$SCRNMAP" ]; then
       echo -ne "\033(K" > /etc/issue
else
       echo "" > /etc/issue
fi
if [ -f /usr/bin/linux_logo ]; then
       /usr/bin/linux_logo -n -o 2 >> /etc/issue
       echo "" >> /etc/issue
fi
cat /etc/issue.net >> /etc/issue
echo "" >> /etc/issue
-------------------------------------

В версии 6.02 все происходит примерно так же. Просмотрите упомянутые выше файлы, и вы убедитесь в этом сами.

11.3.3. Переключение кодировок

Теперь поговорим о том, как "на лету" изменить кодировку символов. Необходимость в этом возникает в тех случаях, когда просматриваешь какой-то файл и вместо читаемого текста видишь непонятную абракадабру. В таких случаях хочется превратить ее в нормальный текст нажатием пары горячих клавиш. Можно, конечно, для каждого из необходимых шрифтов создать специальную команду, записав в небольшой файл приведенные выше команды, естественно соответствующим образом модифицированные. Однако ясно, что это не совсем удобно. В этом отношении хочется работать так же комфортно, как в программе FAR Е. Рошаля, где в том случае, когда просматриваешь файл по клавише <F3> или редактируешь его по <F4>, достаточно набрать <Shift>+<F8> и получаешь возможность перекодировать выводимый на экран текст в любую из нескольких кодировок. Можно считать, что это уже роскошь, но что поделаешь, все мы быстро привыкаем к хорошему, и отказываться уже трудно.

2 июля 2000 г на сайте linux.ru.net появилась сообщение о заплате (патче) к Midnight Commander версии 4.5.50, которая позволяет производить перекодировку как в FAR, по нажатию клавиш <Ctrl>+<T>. Тогда это можно было делать только во встроенной программе просмотра. На сегодня автор патча В. Студенников доработал его, так что перекодировка стала возможна и во встроенном редакторе (см. http://www.linux.zp.ua:8100/mc/ или http://www.sama.ru/~despaire/mc/my-patches.html).

Это что касается перекодировки «на лету». Как видите, такая перекодировка является функцией отдельных программ просмотра файлов. Если перекодировка «на лету» недоступна, то можно перекодировать сам текстовый файл. Для преобразования потока символов из одной кодовой страницы (charset) в другую, в стандарте POSIX существуют утилита iconv и функция iconv(). О других программах перекодировки мы поговорим в гл. 12.


Предыдущий раздел Оглавление Следующий раздел


В. Костромин (kos at rus-linux dot net), "11.3. Русификация консоли" - 14/09/2004 || Библиотека ЛинуксЦентра