Наши партнеры

UnixForum






Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

14 дней жизни одной операционной системы
или впечатления об установке и настройке Red Hat Linux 9 Cyrillic Edition

В.А.Костромин, август 2003 г.

День третий

Сегодня я задался целью добиться корректной русификации текстового, то бишь консольного, режима. Но вначале решил внимательно перечитать "Замечания по русификации" с четвертого дистрибутивного диска. Первая фраза, на которую наталкиваюсь в разделе "Локализация" гласит (мы еще вспомним эту фразу позже):  "Поскольку устанавливаемая теперь в Red Hat Linux по умолчанию языковая среда UTF-8 (Unicode) на данный момент не во всех приложениях работает корректно, возможно, вы захотите использовать старый проверенный KOI8 или использовать и ту, и другую кодировку, в зависимости от стоящих перед вами задач."

И действительно, запуск команды locale показал, что все переменные локализации установлены в значение "ru_RU.KOI8-R".
Но мне, естественно, хочется попытаться работать с Unicode, чтобы хотя бы посмотреть (если уж не понять), что это за зверь такой. В соответствие с рекомендациями "Замечаний по русификации" (ну, или в соответствии с моим пониманием этих "Замечаний") пытаюсь запустить команду redhat-config-language. После ввода по ее запросу пароля root-а она выдала мне нечто не читаемое - какую-то смесь русских букв и псевдографики!

Нахожу в "Замечаниях..." раздел "Консоль", но там тоже ничего вразумительного не нахожу. Правда, там упоминается команда loadkeys. Пытаюсь с ней поиграть и ... УРА! После команды loadkeys ru1 клавиатура выдает нужное "йцукен". Проверяю остальные клавиши на предмет ввода русских букв - ничего неожиданного, только запятая с точкой находятся на клавишах <Shift>+<6> и <Shift>+<7> соответственно, и переключение раскладок теперь производится правым <Alt>. Также отсутствует буква ё, но это все известные особенности раскладки ru1. Хорошо, ввод по-русски идет, посмотрим что с выводом.

Повторяю запуск команды redhat-config-language и снова получаю абракадабру. Предположив, что эта команда является просто скриптом, нахожу ее на диске (в каталоге /usr/bin)  и обнаруживаю, что все команды серии redhat-config-* являются ссылками на consolehelper , а эта последняя является бинарным файлом, так что понять, что именно она делает не так-то просто. Да и объем ее очень мал, что наталкивает на мысль, что она не более чем вызывает какие-то другие программы.

Ладно, не будем тыкаться вслепую. Перечитываю свои конспекты по Линуксу (на основе которых была написана книга [1]), а также ту подборку статей по русификации, которую накопил на своем сайте http://rus-linux.net. К сожалению, большая часть этих статей описывает русификацию старых версий Linux (вплоть до Red Hat 7.3) и поэтому представляет мало интереса, когда речь заходит о работе в режиме UNICODE. Основные источники по вопросу русификации - [2] и [3] говорят о UNICODE очень мало, если не сказать, что вообще ничего. У Богомолова [4] Unicode уже упоминается, даются указания на стандарты, но реальных рецептов пока тоже нет (См. примечание). Так что реальными источниками информации могут служить только две статьи [5,6] человека, скрывающегося под псевдонимом McMCC, две статьи Тимофея Королева [7,8] и статья [9] В.Синицина - наиболее подробный источник сведений на интересующую меня тему. Итак, привожу краткое резюме того, что мне удалось выяснить относительно русификации консоли.

Сначала немного теории. Драйвер консоли (это часть ядра) состоит из драйвера клавиатуры и драйвера экрана. Информация о нажатии клавиши передается драйверу клавиатуры, который может работать в одном из 4 режимов (режим работы задается активным на данный момент приложением):
- В первом режиме драйвер клавиатуры просто передает приложению скан-код клавиши, сгенерированный клавиатурой.
- Во втором случае драйвер преобразует скан-коды в коды клавиш, которые и передаются приложению. Это преобразование выполняется в соответствии с внутренней таблицей драйвера клавиатуры, которая обычно не подлежит изменению.
- В третьем режиме приложению передаются ASCII-коды, которые получаются из кодов клавиш в соответствии с таблицей раскладки клавиатуры. Нужную таблицу можно загрузить командой loadkeys. Файлы с разными раскладками находятся в каталоге /lib/kbd/keymaps/i386/qwerty.
- В четвертом режиме приложению передаются последовательности байтов (от 1 до 6 байтов теоретически, от 1 до 4 байтов практически), представляющие собой закодированные по алгоритму UTF-8 коды символов UNICODE.

Приложение, естественно, может обработать полученные последовательности байтов в соответствии со своими алгоритмами. На процесс обработки может оказать влияние то, какая локаль (то есть соглашения о форматах дат, валюты, порядке сортировки и т.д.) установлена в системе. После обработки приложение направляет драйверу экрана информацию о том, что необходимо отобразить на экране. В потоке выдаваемых приложением байтов содержатся как команды управления (переместить подсветку или курсор, выдать звуковой сигнал, очистить экран, перезагрузить или выключить компьютер и так далее), так и команды вывода символов на экран. Обычно команды управления начинаются с так называемой ESC-последовательности (). При получении ESC-последовательности драйвер экрана выполняет соответствующую команду.

Остальные цепочки байтов содержат указание на вывод какого-то символа на экран. Причем приложение может тоже выдавать эти указания в кодах UNICODE (точнее UTF-8), либо в виде (много-байтовых) ASCII-кодов (причем, вообще говоря, в разных кодировках). Поэтому драйвер экрана тоже имеет два режима работы. В режиме UTF драйвер экрана ожидает получения от приложения символов в кодировке UTF-8. В таком случае он просто преобразует UTF в Unicode (внутренняя кодировка ядра), используя стандартный алгоритм. В байтовом режиме драйвер использует таблицу перекодировки символов (Application Character Map, ACM) для перевода входного потока в Unicode.

После того, как драйвер консоли определил Unicode-код выводимого символа, он обращается к загруженной в него таблице экранного шрифта (Screen Font Map, SFM). Таблицы SFM содержат соответствие между кодами UNICODE и индексами изображений отдельных символов. Индекс служит адресом изображения символа в памяти видеоадаптера.
После определения индекса изображения символа, ядро дает команду видео-подсистеме. Знакогенератор, используя загруженный в него шрифт, воссоздает на экране изображение нужного символа в текущей позиции на экране. Изображения имеют размер 8 на H пикселов, где H равно высоте символа (обычно 8, 14 или 16). Поэтому в памяти видеоадаптера (и в файлах консольных шрифтов) изображения символов представлены цепочкой из H байтов, причем каждый байт кодирует одну строку изображения символа (0 - светлый пиксель, 1 - темный пиксель). Для большинства современных шрифтов и таблица SFM и изображения символов, загружаемые в видеопамять, хранятся в одном и том же файле (признаком этого является расширение .psfu у файла шрифта).

Таким образом, для того, чтобы организовать ввод и вывод символов, нужно:
- установить локаль,
- загрузить клавиатурную раскладку (раскладки хранятся в каталоге /lib/kbd/keymaps),
- загрузить в видеоадаптер шрифт, то есть изображения символов (файлы шрифтов хранятся в каталоге /lib/kbd/consolefonts),
- загрузить в драйвер экрана таблицу SFM (либо из файла шрифта, либо из каталога /lib/kbd/unimaps),
- загрузить таблицу ACM (из каталога /lib/kbd/consoletrans), соответствующую заданной локали.

Необходимо еще отметить, что в ядре Linux отведено место для четырех таблиц ACM, причем первые три фиксированы (это таблицы cp437, vt100, iso01) и только четвертую (user-defined или пользовательскую) можно использовать для вывода однобайтовых кириллических кодировок (например, KOI8-R). Да к тому же каждая виртуальная консоль может одновременно работать только с двумя из этих таблиц, так что максимально возможное число выводимых символов равно 512. Переключение на пользовательскую кодировку осуществляется ESC-последовательностью "\033(K".

Итак, первым делом зададим локаль, установив нужные значения в файле /etc/sysconfig/i18n. Заглянув в каталог /etc/sysconfig/ обнаруживаю там готовую заготовку файла i18n, поименованную i18n.UTF-8. Переименовываю i18n в i18n.KOI8-R и копирую i18n.UTF-8 в i18n. Теперь в этом файле  прописаны следующие значения:

LANG="ru_RU.UTF-8"
SUPPORTED="en_US.UTF-8:en_US:en:ru_RU.UTF-8:ru_RU.ru"
SYSFONT="latarcyrheb-sun16"

Первые две строки понятны. Третья определяет системный фонт. Заглядываю в каталог /lib/kbd/consolefonts и убеждаюсь, что таковой в наличии, причем имеет расширение .psfu, то есть содержит и изображения символов и таблицу SFM. Таблица перекодировки (ACM) в данном случае вроде бы не нужна, поскольку мы работаем в режиме UTF-8. То есть надо обеспечить только загрузку раскладки клавиатуры, которая определяется файлом /etc/sysconfig/keyboard. (мои игры с командой loadkeys ru1 на этот файл влияния не оказали и при следующей перезагрузке я снова получил бы раскладку ru-win). Запускаю команду redhat-config-keyboard, которая предлагает мне на выбор 7 русских раскладок. Вижу среди них "Русская (utf8)" и следуя принятому направлению, ее и выбираю. В файле /etc/sysconfig/keyboard оказываются прописаны две строки:

KEYBOARDTYPE="pc"
KEYTABLE="ru-utf".

Теперь при перезагрузке системы должен отработать инициализационный скрипт /etc/rc.d/rc.sysinit, который среди прочих действий обеспечивает загрузку системного шрифта и клавиатурной раскладки. Для загрузки системного шрифта  вызывается скрипт /sbin/setsysfont, который считывает установки, заданные в  /etc/sysconfig/i18n и  вызывает команду  /bin/setfont, обеспечивающую загрузку шрифта в знакогенератор дисплея и загрузку таблицы SFM в драйвер экрана. Загрузка клавиатурной раскладки осуществляется непосредственно из скрипта /etc/rc.d/rc.sysinit путем вызова команды /bin/loadkeys, аргументы для которой берутся из файла /etc/sysconfig/keyboard.

Вроде бы все необходимые настройки сделаны, так что перезагружаем систему. После входа в систему пробую ввод символов в русском регистре (переключение - по правому <Alt>). В консоли все вводится и отображается нормально. Команда locale выдает значение "ru_RU.UTF-8" для всех переменных локализации. Запускаю  mc. Картинка тоже нормальная. Меню по-русски. А вот ввод русских символов к командной строке под панелями не работает - курсор прыгает вперед, оставляя по несколько пробелов. Та же картина при попытке вводить русский текст во встроенном редакторе. И строка подсказок (hints) пуста. То есть Midnight Commander не умеет работать в UNICODE. Но в "Замечаниях по русификации" сказано, что less умеет. Создаю пустой файл, во встроенном редакторе mc ввожу в него строку символов "йцукенгшщзхъ" (верхний ряд клавиш), выхожу из mc и запускаю команду less test. К сожалению, вижу строку "йЙкенгЙзЙ". Тогда выполняю команду cat > test и ввожу ту же строку символов. Теперь результат команды less test вполне соответствует тому, что я вводил. Вывод: с русским в UNICODE не умеет работать программа mc.
Создаю файл с именем "тест" (русскими буквами) и запускаю команду ls. В ее выводе вижу среди прочих и слово "тест". Значит ls тоже русифицирована.

Но проверять подряд все команды, чтобы определить, какая работает корректно, а какая нет, что-то не хочется. Подойдем к вопросу с другой стороны. Когда и где необходим русский язык и русские символы? В первую очередь - это при вводе текста, то есть в файлах, создаваемых консольными текстовыми редакторами. К сожалению, любимый мой редактор - встроенный в Midnight Commander  редактор CoolEdit с этой задачей не справляется (пока!). Затем - при просмотре файлов, содержащих текст на русском языке. Тут надо опять же иметь в виду, что файл может содержать текст не только в UTF8, но и в более традиционных кодировках. Значит просмотрщик должен понимать (или уметь оперативно менять) кодировку. Это что касается текстов, содержащихся в файле. Ну и имена файлов могут быть введены русскими символами, то есть файловые менеджеры и команды работы с файлами должны быть "русифицированы". Эти три основных класса ПО я и решил рассмотреть.

Начнем с редакторов. Раз редактор из mc не работает, попробуем другие. Поискал на диске файлы по шаблону  "*edit", я , к сожалению, ничего не нашел. Так что пока единственным средством для создания текстовых файлов (в консоли) у меня остается команда cat. С ее помощью создал в домашнем каталоге файл  с именем "тест.utf", содержащий все символы русского и латинского алфавитов.

Теперь программы просмотра. Как мы уже видели, команда less русифицирована, так что просмотреть созданный файл тест.utf вполне можно, хотя и не очень удобно. Далее я случайно вспомнил о консольном браузере lynx. Запустив его, я обнаружил, что он русифицирован, но тоже весьма коряво. Меню вроде выводится русскими буквами, но многие строки не читаются. И русские имена файлов он не понимает, во всяком случае открыть файл тест.utf он не сумел.

Раз уж речь зашла о просмотре файлов, то естественно вспоминается необходимость просмотра подсказок, то есть man-страниц! Вспомнив о них, я проверил как выводятся русифицированные страницы. Заглянул в каталог /usr/share/man/ru/man1, посмотрел для каких команд имеются файлы, и вывел командой man некоторые из этих страниц. Читать можно, но о качестве вывода говорить не приходится - пробелы появляются там, где их быть не должно и отсутствуют там, где они необходимы.

Еще одна идея из тех, которые попутно пришли в голову, - посмотреть, а может в дистрибутиве RH9CE не та версия Midnight Commander-а. Ведь в дистрибутив ASP входит версия этого файлового менеджера, позволяющая переключать кодировки. Может среди них есть и UNICODE? Но, к сожалению, оказалось что UNICODE в число имеющихся кодировок не входит. Жаль, от FAR-а отстаем!

Ну, ладно, может быть в графическом режиме дела с русификацией обстоят лучше. Впрочем,  сегодня проверять уже некогда, снова пора спать.

Продолжение следует...

Список литературы и ссылки.

  1. В.А.Костромин, "Linux для пользователя", изд. БХВ-Петербург, 2002 год, серия "Самоучитель", 650 стр. 
  2. Е.Балдин, "Cyrillic-HOWTO-russian Очень полный материал по вопросу русификации Линукс, но о UNICODE и UTF-8 там ничего нет.
  3. Хороший, на мой взгляд, материал по русификации содержится в faq конференции fido7.ru.linux  ( http://www.sensi.org/~ak/linuxfaq), где большой раздел о русификации.
  4. Неплохой раздел есть в заметках Сергея Евгеньевича Богомолова. (смотри также С.Богомолов, i18n).
  5. McMcc, "Переход с RedHat-7.x на RedHat-8.0"
  6. McMcc, "Настройка RedHat 9 на русскую локаль KOI8-R"
  7. Т.Королев, "Русификация RedHat Linux 8.0"
  8. Т.Королев, "Русификация RedHat Linux 9" В статье описываются все действия необходимые для того, чтобы полностью русифицировать X Window в девятой версии дистрибутива RedHat Linux.
  9. Валентин Синицын, "Red Hat Linux 8.0: проблемы кириллизации консоли" (Та же статья на сайте Linux Center)


Примечание: После появления этой моей заметки С. Богомолов прислал мне следующее письмо:
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    Date: Вт, 02 сен 2003  19:38:57
    From: Sergej E Bogomolov 
 Subject: к "Впечатления об установке и настройке RH9..."
--------------------------------------------------------------------------------

Добрый день!
Про борьбу с уникодом у меня есть 
(но только для RH 8.0 и в графическом режиме):
  http://www.bog.pp.ru/work/linux_install_RH80_desktop.html

p.s. собственно, русский язык в консоли неинтересен совершенно. 
Я использую текстовый режим только, если с одного компьютера захожу 
на другой по ssh. Но в этом случае используется xterm/gnome-terminal,
в которых борьба за русский язык ведется отдельно.
-- 
Sergej E. Bogomolov         http://www.bog.pp.ru
Возврат к тексту