Когда мне принесли 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 софтом.
Или читай сразу Русификация 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 !
Но предположим, что мы неплохо разбираемся в 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...
Новые глюки. На этот раз в обычном 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.
Комментарии к предыдущей заметке (в конце).
День славянской письменности. Вообще-то, это юмор...
--
-=AV=-