Проблемы локализации в RedHat 5.2 (GNU libc 2.0.7).

    Когда мне принесли CD c новой версией RedHat Linux 5.2 (Apollo), я, скажем так, слегка волновался. Наконец, то, думал я, появится версия Linux в которой проблемы локализации если не исчезнут, то хотя бы сойдут на уровень косметических недочетов.

    Как бы не так!

    Итак, "из чего же" сделан RedHat 5.2 ? Во-первых, это libc6 (glibc2) дистрибутив. На библиотеку glibc RPM рапортует как  glibc-2.0.7-29 . На самом деле, официально такой библиотеки нет, последняя на ftp://ftp.gnu.org - glibc-2.0.6 . То, что входит в состав RedHat 5.2 - это snap glibc-2.0.7-981012 с огромным количеством патчей от RedHat. Также, в дистрибутив входит libc5 (libc-5.3.12-28) для совместимости со старым binary софтом.

    Одна из RedHat-овских правок добавляет поддержку руского языка в KOI8-R. Но давайте вспомним теорию


   По новому стандарту (POSIX.2 приложение E (?)) значения локализации записываются в форме:

	language_TERRITORY.Codeset

или формально:

	language[_TERRITORY[.Codeset[@modyfier]]]

   T.e. допустимы короткие именования значений locale, которые часто оформляются как aliases (псевдонимы) полного наименования. Hапример "C" --> "POSIX" --> "en_US".

    Стандарт ISO 639 описывает "language names", ISO 3166 - "territory names".


    По стандарту, language для Росии будет "ru", а TERRITORY - "RU". Значение TERRITORY "SU" больше не существует.

    С кодировками все более менее понятно. За период "темных времен" их расплодилось предостаточно :
IBM866
KOI8-R
ISO8859-5
Windows-1251
X-mac-cyrillic
и еще несколько совсем редких.

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


    Итак, включаю локализацию :

$ export LANG=ru_RU

    Проверяю утилитой locale :

$ locale mon

ощрпЮО;дурЮпшО;?пЮБ;°ъЮушО;?пы;ёНщО;ёНшО;°рсЦАБп;аущБОяЮО;?зБОяЮО;?чОяЮО;?узпяЮО

$ 

    OOSP ! Угу. Зачем мне ISO8859-5 ???   Проверим, что у нас есть на выбор :

$ locale -a

...

ru

ru_RU

ru_SU

russian

...

    Включаю :

$ export LANG=ru_SU

$ locale mon

Января;Февраля;Март;Апреля;Май;Июня;Июля;Августа;Сентября;Октября;Ноября;Декабря

$

    Прекрасно. За исключением несуществующей страны SU. Но раз в стандарте написано [.CODESET] , попробую явно задать CODESET.

$ export LANG=ru_RU.KOI8-R

    Проверяем :

$ locale mon

ощрпЮО;дурЮпшО;?пЮБ;°ъЮушО;?пы;ёНщО;ёНшО;°рсЦАБп;аущБОяЮО;?зБОяЮО;?чОяЮО;?узпяЮО

$

    Но может быть данного CODESET нету ? Нет, есть :

$ locale -m

...

CP1251

ISO-8859-5

KOI8-R

...

    Проблема оказалась даже хуже, чем я предполагал. Библиотека glibc2 (в базовой поставке) принципиально не воспринимает параметр CODESET. Естественно, это оказывает разрушающее воздействие также на систему  NLS (кодировка сообщений). А праметр CODESET просто игнорируется.

    Именно для обхода этой "нефункциональности" и была введена несуществующая страна _SU и новое значение локализации ru_SU. Сначала в виде "заплатки" от RedHat, а потом и в alpha версии glibc 2.1

    Итак, отныне (как решил за нас RedHat):

ru_RU ISO8859-5
ru_SU KOI8-R

    Нестандартных решений прибыло ! На этот раз от GNU и RedHat !


Дополнение на 21 Feb 1999

    Но предположим, что мы неплохо разбираемся в POSIX locale и хотим сами установить новое значение локализации :

$ localedef -c -i ru_RU -f KOI8-R ru_RU.KOI8-R

Computing table size for character classes might take a while... done

Computing table size for collation information might take a while... done

$ 

    Проверяем :

$ locale -a

...

ru

ru_RU

ru_RU.koi8r

ru_SU

russian

...

    Опять не легче, поскольку наш горячо любимый KOI8-R (описанный в стандарте RFC-1489) превратился в жалкий koi8r ! А почему ? Да потому что Ulrich Drepper добавил в localedef такое :

/* Normalize codeset name. There is no standard for the codeset

   names. Normalization allows the user to use any of the common

   names. */

static const char *

normalize_codeset (codeset, name_len)

     const char *codeset;

     size_t name_len;

{

    Непонятно, почему Ulrich считает, что нет стандарта на CODESET. Достаточно зайти на http://www.isi.edu/in-notes/iana/assignments/character-sets и получть список всех CHARSET, зарегистрированных в IANA, даже с Alias:... Можно придраться, что CODESET != CHARSET, но знаете ли...

    Что с этим делать ?

    Можно переименовать каталог :

$ mv /usr/share/locale/ru_RU.koi8r /usr/share/locale/ru_RU.KOI8-R

поскольку создает-то localedef все правильно.

    Можно поправить /usr/share/locale/locale.alias, но хотелось-то сразу, из коробочки...

    На мой вопрос Ulrich-у, что мол так плохо, я получил ответ : "glibc 2.2 will have support for all the automatic character set conversions." Это при том, что сейчас glibc 2.1 alpha. Не любят нас буржуи...

    Однако, не везде все так плохо. Вот пример (свежепоставленная система) :

$ ls -l /usr/share/locale

...

lrwxrwxrwx  1 root  bin  11 Aug 30 21:14 ru -> ru_RU.ISO_8859-5

lrwxrwxrwx  1 root  bin  11 Aug 30 21:14 ru_RU -> ru_RU.ISO_8859-5

lrwxrwxrwx  1 root  bin  11 Aug 30 21:14 ru_SU -> ru_RU.KOI8-R

lrwxrwxrwx  1 root  bin  11 Aug 30 21:14 ru_SU.ISO_8859-5 -> ru_RU.ISO_8859-5

lrwxrwxrwx  1 root  bin  12 Aug 30 21:14 ru_SU.KOI8-R -> ru_RU.KOI8-R

lrwxrwxrwx  1 root  bin  11 Aug 30 21:14 ru_SU.CP866 -> ru_RU.CP866

...

drwxr-xr-x   2 bin   bin   512 Aug 30 21:14 ru_RU.CP866

drwxr-xr-x   2 bin   bin   512 Aug 30 21:14 ru_RU.ISO_8859-5

drwxr-xr-x   2 bin   bin   512 Aug 30 21:14 ru_RU.KOI8-R

...

$

    Как видите, есть поддержка ru --> ru_RU --> ru_RU.ISO_8859-5 и пресловутого ru_SU --> ru_RU.KOI8-R (все сделано на symlinks). Но к сожалению, это не Linux...


Дополнение на 3 марта 1999.

    Новые глюки. На этот раз в обычном ls. Не сортирует имена файлов.

    Читаем man ls :

...

  This manual page documents the GNU version of ls. dir and

  vdir are versions of ls with different default output for-

  mats. These programs list each given file or directory

  name. Directory contents are sorted alphabetically. For

  ls, files are by default listed in columns, sorted verti-

  cally, if the standard output is a terminal; otherwise

  they are listed one per line. For dir, files are by

  default listed in columns, sorted vertically. For vdir,

  files are by default listed in long format.

...

    Проверим ?

$ locale

LANG=ru_RU.KOI8-R

LC_CTYPE="ru_RU.KOI8-R"

LC_NUMERIC="ru_RU.KOI8-R"

LC_TIME="ru_RU.KOI8-R"

LC_COLLATE="ru_RU.KOI8-R"

LC_MONETARY="ru_RU,KOI8-R"

LC_MESSAGES="ru_RU.KOI8-R"

LC_ALL=

$ 

    Установленная locale - самодельная : изготовлена через localedef, а потом mv.

$ ls -l /usr/share/locale/ru_RU.KOI8-R

total 45

-rw-rw-r-- 1 root root 29370 Мар  2 19:02 LC_COLLATE

-rw-r--r-- 1 root root 10424 Мар  2 16:05 LC_CTYPE

drwxrwxr-x 2 root root  1024 Мар  2 19:03 LC_MESSAGES

-rw-rw-r-- 1 root root    95 Мар  2 19:02 LC_MONETARY

-rw-rw-r-- 1 root root    27 Мар  2 19:02 LC_NUMERIC

-rw-rw-r-- 1 root root   492 Мар  2 19:02 LC_TIME

$

    LC_COLLATE есть. Обратите внимание -- даты русские, то есть LC_NUMERIC работает. Консоль русифицирована в KOI8-R.

$ ls -l

total 1

-rw-rw-r--   1 alec   alec    0 Мар  3 19:02 Anna

-rw-rw-r--   1 alec   alec    0 Мар  3 19:03 Bravo

-rw-rw-r--   1 alec   alec    0 Мар  3 19:03 Center

-rw-rw-r--   1 alec   alec    0 Мар  3 19:07 Zero

-rw-rw-r--   1 alec   alec    0 Мар  3 19:03 anna

-rw-rw-r--   1 alec   alec    0 Мар  3 19:03 bravo

-rw-rw-r--   1 alec   alec    0 Мар  3 19:03 center

-rw-rw-r--   1 alec   alec    0 Мар  3 19:07 zero

-rw-rw-r--   1 alec   alec    0 Мар  3 19:10 юлия

-rw-rw-r--   1 alec   alec    0 Мар  3 19:03 анна

-rw-rw-r--   1 alec   alec    0 Мар  3 19:04 борис

-rw-rw-r--   1 alec   alec    0 Мар  3 19:06 центр

-rw-rw-r--   1 alec   alec    0 Мар  3 19:05 виктор

-rw-rw-r--   1 alec   alec    0 Мар  3 19:10 Юлия

-rw-rw-r--   1 alec   alec    0 Мар  3 19:02 Анна

-rw-rw-r--   1 alec   alec    0 Мар  3 19:04 Борис

-rw-rw-r--   1 alec   alec    0 Мар  3 19:06 Центр

-rw-rw-r--   1 alec   alec    0 Мар  3 19:05 Виктор

$

    Все плохо. Сортировка юабцЮАБЦ -- это сортировка по кодам в KOI8-R. Данный ls из RedHat 5.2 (Linux/GNU). Попробуем на другой системе : старенькая FreeBSD 2.2.5 пойдет ? Русификация консоли в KOI8-R. Утилиты locale там все еще нет. Однако сортировка в ls работает :

$ uname -sr

FreeBSD 2.2.5-RELEASE

$

$ echo $LANG

ru_RU.KOI8-R

$

$ ls -l

total 0

-rw-r--r-- 1 root wheel 0 мар 2 23:01 Анна

-rw-r--r-- 1 root wheel 0 мар 2 23:01 Борис

-rw-r--r-- 1 root wheel 0 мар 2 23:01 Виктор

-rw-r--r-- 1 root wheel 0 мар 2 23:02 Центр

-rw-r--r-- 1 root wheel 0 мар 2 23:02 Юлия

-rw-r--r-- 1 root wheel 0 мар 2 23:01 анна

-rw-r--r-- 1 root wheel 0 мар 2 23:01 борис

-rw-r--r-- 1 root wheel 0 мар 2 23:01 виктор

-rw-r--r-- 1 root wheel 0 мар 2 23:02 центр

-rw-r--r-- 1 root wheel 0 мар 2 23:02 юлия

$ 

    Подкрутить надо что-то в консерватории, однако...


    Дополнительная информация :

Locale "AS IT IS" Локализация "Как она есть" - введение в POSIX locale.

Большой Журналистский Секрет. Что говорить про Linux.

Еще один борец со стандартами : KSI Linux.

Комментарии к предыдущей заметке (в конце).

День славянской письменности. Вообще-то, это юмор...


alec@sensi.org

--
-=AV=-


last change : 30/03/99


Banner.Novgorod.Ru