Проблемы локализации в 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 софтом.

  1. Теория.
  2. Проверка.
  3. Сделай сам.
  4. Как исправить ?
  5. А вот еще !
  6. Что читать ?

    Или читай сразу Русификация Linux RedHat 5.2 .


   Одна из RedHat-овских правок добавляет поддержку locale руского языка в 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, и таблицы перекодировок одной в другую давно известны. Пусть живут. (См. Charset и его имя).


    Итак, RedHat 5.2. Включаю локализацию :

$ 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] , попробую задать его явно.

$ export LANG=ru_RU.KOI8-R

    Проверяем :

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

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

$ locale -m
...
CP1251
ISO-8859-5
KOI8-R
...

    Проблема оказалась даже хуже, чем я предполагал. RedHat 5.2 glibc2 (в базовой поставке) принципиально не воспринимает параметр CODESET locale. Естественно, это оказывает разрушающее воздействие также на систему  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:... (См. Charset и его имя)


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

    Самое простое решение : скомпилировать 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
$ 
$ cd /usr/share/locale
$ mv ru_RU.koi8r ru_RU.KOI8-R

    поскольку создает-то localedef все правильно. После этого проставить LANG=ru_RU.KOI8-R и радоваться жизни (См. Как включить локализацию и Русификация RedHat 5.2).

    Можно также поправить /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 : 14.08.1999