- Валентин Синицын, 2002 -

30 сентября компания Red Hat, Inc. выпустила восьмую версию своего дистрибутива Linux. Как известно, "точка-ноль" дистрибутивы приносят не только новые возможности, но и новые проблемы...

Не обошла сия печальная доля и Red Hat Linux 8.0. Цель этой статьи - помочь Вам обойти "подводные камни" в процессе русификации консоли (далее под этим термином мы будем понимать экран монитора в текстовом режиме, отодвигая таким образом клавиатуру на второй план).

Мы начнем с "незыблемых основ" русификации Linux, после чего перейдем к тонкостям, относящимся только к Red Hat 8.0. Поскольку каждое приложение имеет свою специфику, мы ограничимся, пожалуй, самым популярным из них - файловым менеджером Midinght Commander. Русификация остальных программ происходит либо автоматически (ls, rpm и другие "простые" утилиты), либо не представляет существенной проблемы (lynx). В любом случае, подробную информацию по каждой конкретной программе (а также многое другое) всегда можно найти в Cyrillic-HOWTO Е.М. Балдина.

Азбука кириллизации

Рассмотрим схематически процесс вывода на экран некоторого символа "x":
  • Прикладная программа, желая вывести "x" на экран, записывает в стандартный поток вывода соответствующую ему последовательность байт, которая в конечном счете достигает драйвера консоли (часть ядра Linux). Если драйвер консоли в этот момент находится в режиме UTF, он предполагает, что входные данные были записаны именно в этой кодировке, и использует стандартный алгоритм для преобразования UTF в Unicode (внутренняя кодировка ядра). В противном случае (т.н. "однобайтовый" или "ASCII" режим) драйвер использует таблицу перекодировки символов (Application Character Map, ACM) для перевода входного потока в Unicode. В ядре Linux отведено место для четырех таблиц ACM: cp437, vt100, iso01 и user-defined. Последнюю из них как раз и можно использовать для вывода однобайтовых кириллических кодировок (например, KOI8-R). Выбор пользовательской кодировки осуществляется ESC-последовательностью "(как правило, она генерируется автоматически соответствующими утилитами, хотя есть нюансы - см. bug #76470 в RedHat Bugzilla).
  • Теперь, когда драйверу консоли известен Unicode-код "x", он должен определить, какой глиф в текущем шрифте ему соответствует. Для этого используется таблица экранного шрифта (Screen Font Map, SFM). Для большинства современных шрифтов таблица SFM хранится в том же файле, что и глифы (признаком этого является расширение .psfu у файла шрифта).
  • После определения номера глифа, ядро дает команду видеоподсистеме. Знакогенератор, используя загруженный в него шрифт, воссоздает на экране изображение "x"

Для кириллизации консоли в Linux используются два конкурирующих пакета: kbd и consoletools. Последний применялся в Red Hat версий 6.x-7.x, в более ранних и более поздних используется kbd. Оба пакета имеют сходную функциональность. Все необходимые для работы этих пакетов файлы хранятся в директории /lib/kbd: /lib/kbd/consolefonts (файлы шрифтов), /lib/kbd/consoletrans (ACM), /lib/kbd/unimaps (SFM) и /lib/kbd/keymaps (клавиатурные раскладки).

В дальнейшем по понятным причинам будем предполагать, что используется пакет kbd. Утилита setfont из этого пакета позволяет как загружать шрифты, так и устанавливать таблицы перекодировки ACM (параметр командной строки -m) и SFM (-u). Параметры можно комбинировать. Так, например, команда setfont Cyr_a8x16 -m koi2alt устанавливает шрифт Cyr_a8x16 и ACM-таблицу koi2alt.

Рассмотрим теперь, как организован процесс русификации в Red Hat 8.0. В первую очередь обратимся к файлу /etc/sysconfig/i18n. В нем определяются значения следующих переменных:

  • SYSFONT - имя шрифта. Расширение указывать необязательно.
  • SYSFONTACM - имя ACM-таблицы.
  • UNIMAP - имя SFM-таблицы.
  • LANG - определяет локаль (locale). Если название локали заканчивается на "UTF-8" (например, "ru_RU.UTF-8"), драйвер консоли переводится в режим UTF. Список установленных в системе локалей возвращается командой locale -a.
В процессе инициализации системы сценарий rc.sysinit выполняет /etc/sysconfig/i18n, после чего происходит запуск скрипта /sbin/setsysfont, загружающего шрифт и указанные таблицы перекодировки. Одновременно устанавливается клавиатурная раскладка, имя которой хранится в файле /etc/sysconfig/keyboard(переменная KEYTABLE).

Теперь, когда мы представляем себе общую схему русификации консоли, рассмотрим два конкретных способа научить Red Hat говорить по-русски.

Путь первый, новаторский

Предпочтительной кодировкой в Red Hat 8.0 является UTF-8. Устанавливаемые по умолчанию шрифт "latarcyrheb-sun16" и локаль "en_US.UTF-8" позволяют корректно отображать символы латинского, русского и арабского алфавитов, а также иврита. Обратите внимание, что для многобайтовых UTF-локалей не столь важно, к какому языку они относятся: единственным ощутимым изменением при использовании "ru_RU.UTF-8" будет смена формата представления даты, времени, валюты и языка интерфейса некоторых программ (собственно, UTF-8 и Unicode и были созданы для того, чтобы обеспечить единообразие работы с любым алфавитом). Таким образом, если Вы собираетесь русифицировать консоль Red Hat в UTF-режиме, Вам можно позавидовать - всю необходимую работу за Вас уже проделали разработчики дистрибутива. И посочувствовать: Вам это особенно не поможет.
Разъясним последнее утверждение. Используемый по умолчанию шрифт уже содержит символы кириллицы, а консоль работает в режиме UTF, поэтому символы русского алфавита должны выводиться без дополнительных усилий. К сожалению, в данной схеме возникает неприятный побочный эффект - сильно затрудняется вывод данных в не-UTF кодировке (например KOI8-R). И если с кириллицей в именах файлов на vfat-разделах справиться достаточно легко (в параметрах монтирования в /etc/fstab необходимо указать "codepage=866,iocharset=utf8" вместо традиционного "codepage=866,iocharset=koi8-r"), с русскоязычными документами придется основательно повозиться: Midnight Commander 4.5.55 не умеет перекодировать в UTF-8 "на лету". Кроме того, некоторые приложения могут некорректно работать в UTF-локали, поскольку не поддерживают многобайтовые кодировки (за примером далеко ходить не надо - взять все тот же Midnight Commander). В других программах могут пропасть символы псевдографики. В довершение всего, консоль теряет возможность отображать цвета с кодом больше 7 (т.е. все "яркие"), так что файлы и директории на панелях MC оказываются совершенно неразличимыми. Если все это Вас не смущает, Вам остается только поставить соответствующую раскладку клавиатуры (например, ua-utf), и - поздравляем! Ваша консоль успешно русифицирована.

Путь второй: старый, проверенный

Данный способ является своеобразным "шагом назад", поскольку подразумевает, что Вы будете использовать устаревшую кодировку KOI8-R вместо современной UTF. Если Вы занимались русификацией предыдущих версий Red Hat,часть нижеизложенного будет Вам знакома. Остальные читатели в случае необходимости могут обратиться за детальной информацией к Cyrillic-HOWTO.

Итак, попробуем применить хорошо известное решение: SYSFONT="Cyr_a8x16" и SYSFONTACM="koi2alt" (о его плюсах написано все в том же HOWTO). К сожалению, в таком виде оно не работает. Причина кроется в скрипте /sbin/setsysfont, который почти не менялся со времен consoletools. Любой заглянувший в него не может не обратить внимания на вопиющую дискриминацию - для kbd (setfont) не поддерживается переменная SYSFONTACM! Я отправил сообщение об этой ошибке (включая исправленную версию сценария) на bugzilla.redhat.com, исправление должно появиться в initscripts 6.96-1 или более поздней версии. После исправления этой ошибки (например, путем скачивания моей версии setsysfont) и установки вашей любимой клавиатурной раскладки (что-нибудь типа ru*, но никак не *-utf!) не забудьте удалить подстроку "UTF-8" из имени локали, поскольку иначе консоль переключится в режим UTF и откажется принимать Вашу KOI8-R.

После всех этих манипуляций файл /etc/sysconfig/i18n будет иметь следующий вид: LANG="en_US"
SUPPORTED="по умолчанию"
SYSFONT="Cyr_a8x16"
SYSFONTACM="koi2alt"

Если Вашей целью было создание "пан-европейской" версии Linux (это когда русские буквы отображаются, но все общение с системой происходит на английском языке), Вас опять можно поздравить. Если нет - читайте дальше.
Для окончательной русификации (установки российского формата даты, времени, валюты, русскоязычных сообщений в отдельных программах) следует установить соответствующую локаль, например "ru_RU.koi8r". К сожалению, здесь нас опять поджидают проблемы - в такой среде у Midnight Commander и некоторых других программ (setuptools, например) пропадет псевдографика. MC, помимо этого, опять отказывается выводить русские буквы где-либо, кроме меню, да и в нем - в искаженном виде. "Корень зла" во всех случаях один - используемые библиотеки (NCurses, S-Lang) скомпилированы с поддержкой Unicdoe, в то время как она нам совсем не нужна. Необходимо перекомпилировать их в однобайтовом режиме (вот он, истинный шаг назад - мы, по сути, устраняем изменения, внесенные в Red Hat Linux после версии 7.3). Рассмотрим эту процедуру на примере Midnight Commander. Его "излечение" проходит в два этапа:

  1. Откомпилируйте NCurses в без поддержки UTF (./configure --disable-widec)
  2. Перекомпилируйте MC с использованием NCurses вместо традиционного S-Lang (./configure --with-ncurses)
Подробную информацию о других ключах компиляции ищите в документации к соответствующим пакетам.

На мой взгляд, наиболее приемлемым вариантом русификации является "пан-европейский" KOI8-R. UTF-режим, безусловно, удобен, но еще недостаточно отлажен. Думается, что им вполне можно будет пользоваться в версиях 8.2-8.3. Полная русификация в не-UTF режиме - слишком трудоемкая операция. Если русскоязычный интерфейс для вас превыше всего, имеет смысл обратить внимание на KDE, благо с ее русификацией особых проблем не возникает.

Автор выражает благодарность Шабунио Ю.А. за ценные идеи и плодотворную дискуссию.