Каждый вступающий на тропу освоения Линукса, рано или поздно сталкивается с проблемой кодировок. Оказывается, что мир вокруг заполнен файлами, содержащими информацию в самых различных кодировках, и вопросы взаимодействия решены не очень...
Подробнее см. раздел «Причины появления» библиотеки NATSPEC.
В общем случае в системе отсутствует:
Стандартизация очень важна, особенно при разработке операционных систем. Все ключевые понятия должны быть определены.
Как написано в руководстве по нашим дистрибутивам, «Файловая система Linux... является единым деревом». Тут нет понятия ext3, reiserfs, FAT32 или NTFS. И фактически все файлы в этом дереве имеют названия в определённой кодировке.
Общей рекомендацией является (для десктопной машины) ставить систему в такую же кодировку, как в Windows.
Кодировка windows-1251 имеет множество преимуществ перед koi8-r, созданной для решения одной единственной задачи — возможности прочитать сообщение, даже при утрате старшего бита в каждом байте. В настоящее время эта проблема неактуальна. Преимущества же кодировки windows-1251:
Достичь цели, когда только в одном конфигурационном файле системы будет указана кодировка. Вторым этапом предлагается установить эту кодировку в UTF-8.
Конкретные шаги:
В общем: систему, более пригодную к переходу на UTF-8, взаимодействующую с ресурсами UTF-8-систем, и после перехода на UTF-8 – взаимодействующую с другими системами, и данными, не поддерживающими UTF-8.
Сюда записываются возражения, даже и не очень обоснованные. Желательно найти им ответ.
DenisSmirnov /25.02.2005 15:26/ Как и в любой другой не-unicode системе он будет вынужден пользоваться латиницей
DenisSmirnov /25.02.2005 15:26/ Отлавливанием виновного, и поручением ему перекодировки. Внутри организации должны действовать стандарты, и один из них — используемая кодировка хранения данных. Это существенно исключительно для nfs и ftp, в CIFS подобных проблем нет (перекодировка есть штатно);
DenisSmirnov /25.02.2005 15:26/ Описания всех возможных кодировок у нас и так есть — libiconv, на которую уже переползла та же Samba. У неё, правда, есть один серьёзнейший недостаток, из-за которого links на неё не перейдёт никогда — отсутствие возможности преобразовать символы в близкие по смыслу (например русские буквы при перекодировке в iso8859–1 отображать транслитом);
/VitalyLipatov // В libnatspec хранится описание *соответствия* всех возможных кодировок, а не просто перечень. К тому же в libnatspec добавлена возможность транслитерировать несоответствующие символы.
Статус: Есть готовый файл для profile
В gtk есть обработка переменной окружения G_FILENAME_ENCODING, которая у нас _не_ устанавливается, поэтому gtk предполагает, что она соответствует локали. При этом всё ломается, если я хочу запустить программу из другой локали (LANG=ru_RU.UTF-8 или LANG=ru_RU.CP1251) при основной koi8-r.
Так же GLIB обрабатывает переменную G_BROKEN_FILENAMES. Если она установлена, GLib предполагает, что названия файлов хранятся в кодировки локали, а не в UTF-8. Но G_FILENAME_ENCODING имеет больший приоритет.
TODO:
1. Ни к чему каждый раз после установки раскомментировать в конф. файле строчки про кодировку (unix/display charset), когда они должны устанавливаться в кодировку файловой системы / локаль автоматически.
DenisSmirnov /25.02.2005 15:26/Для сервера ручная настройка ещё может иметь какой-то разумный смысл, для клиента же — автоугадав обязателен
2. При монтировании удалённой файловой системы через smbmount (и mount -t cifs скорее всего тоже) опять же требуется указать кодировку своей системы (iocharset)
DenisSmirnov /25.02.2005 15:26/ iocharset давно надо брать из текущей локали по-умолчанию
Статус: есть патч для mount
TODO: Одновременно можно внести в mount поддержку /etc/fstab.d?
Тут я хотел бы пояснить, что в стандартной системе должна быть команда mount и она должна работать правильно. HAL – это хорошо, но это другое решение и надстройка более высокого уровня. Она не отменяет простого использования mount.
Бесконечное количество раз люди бьются с fstab, записывая туда разные iocharset, nls_ и пр. Но ведь можно же брать эти параметры (по умолчанию) из кодировки файловой системы.
TODO:
Rock Ridge? предполагать в UTF-8, перекодировать, если валидна.
Статус: есть патч для mkisofs и isoinfo
Статус: у меня претензий нет
Там происходит перекодирование названий файлов в досовскую кодировку. Скорее всего, используется кодировка локали.
TODO: автоматизация заполнения config.sys для установки внутренней локали
Поскольку для FTP никаким образом не определено задание кодировок, обращаться из одной системы в другую за файлами, имеющими название из не ASCII-диапазона, невозможно.
В proftp 1.3.1 добавился модуль mod_lang (поддержка команды “LANG” в соответствии с интернационализацией по RFC2640)
Варианты решения:
(Как частный вариант есть http://linux.kiev.ua/details.html?&L=1&cHash=f4c7be3c1a&tx_ttnews[backPid]=87&tx_ttnews[pointer]=2&tx_ttnews[tt_news]=550
Статус: у меня претензий нет
В основном проблема с кодировками названий файлов не возникает (решена за счёт предположения соответствия кодировки локали и файловой системы) – идеально, если бы это решалось вне проекта.
TODO: консольные сообщения не перекодируются в кодировку локали (что с wcmd?)
Как правило, в Windows для кодирования названий файлов в архивах используется OEM-кодировка (DOS), в то время как в Linux названия записываются в кодировке файловой системы. И ничего не сдвинуто в этом направлении...
Подлежит уточнению:
Предлагается ввести перекодирование названий при работе с подмонтированными файловыми системами, подразумевая в них UTF-8.
Модули поддержки «чужих» файловых систем как правило имеют параметр iocharset, задающий внутреннюю кодировку названий файлов для перекодирования из «чужого» Юникода. Это относится к isofs, udf, vfat, ntfs, jfs
Для vfat имеется умолчание в ядре: FAT_DEFAULT_CHARSET, FAT_DEFAULT_CODEPAGE, по умолчанию присваиваемые iocharset и codepage соответственно, но это константы, что нам не подходит.
DenisSmirnov /25.02.2005 15:31/ Мысль : насколько просто внедрить дополнительный параметр в суперблок ext3, reiserfs4, xfs (основных используемых FS)?
В JFS предусмотрен iocharset, позволяющий перекодирование смонтированной системы (как я понимаю, в JFS подразумевается UTF8). Можно посмотреть, как это сделано там и рекомендовать разработчикам.
Вообще нужно сделать выбор: указывать кодировку в файловой системе или подразумевать, что она – в UTF-8.
Средство перекодирования файловой системы налету (через fuse?)
DenisSmirnov /24.02.2005 19:14/ Использование для этой цели fuse это очень хорошее временное решение
Кодировку на коротких названиях в FAT можно предполагать на основании кодировки файловой системы (для koi8-r/cp1251 будет cp866), для длинных названий на FAT/NTFS известно какая кодировка. А для остальных файловых систем ext?/reiserfs/xfs нужно вводить хранение кодировки или иметь предубеждение, что она там в UTF-8. Также потребуется перекодирование подмонтированной системы.
Получается, ядро должно иметь информацию о кодировке. Кстати, если хранить названия файлов в произвольной кодировке, можно избежать перекодирования, которое будет производится только при различии кодировкой локальной и на монтируемой файловой системе.
Вячеслав Диконов:
Имею программу, у которой своя собственная внутренняя система локалей (VDR). Там гвоздями и стандартами DVB-вещания забито, что русский всегда идет в iso8859–5. Нет никаких внутренних средств перекодировки или поддержки системной локали, при этом нужно писать и читать много файлов, а файлам автоматически даются русские имена.
Может быть добавить в библиотеку функцию, позволяющую прозрачно заменять обычные обращения к объектам файловой системы в C и автоматически приводить имена к заданной кодировке, в каком бы виде они не хранились на реальных носителях? А также при записи преобразовывать имя из заданной кодировки в любую, какая используется на диске.
К VDR есть даже свои коммандер и консоль... Задача в том, чтобы видеть через преобразователь кодировок все съемные носители, все разделы с мультимедийными файлами и т.п. Кстати, набирать длинные команды и монтировать через обычный пульт ДУ слишком тяжело, а лавиатуры/мыши у VDR-машин часто вообще нет.
Еще проблема – включение в специаизированные дистрибутивы, которые ставятся на компы-ресиверы. Там все обрезано под ноль. Это я к тому, что решение должно быть маленьким и включаться минимальными движениями пользователя.
Алексей Морозов:
Единственным решением, которое худо-бедно может претендовать на некоторую универсальность (ну, помимо банального использования содержимого /etc/sysconfig/i18n) является организация (через dbus, вестимо, куда ж нынче без него) _обратной связи_ между HAL и пользовательским сеансом. То есть, сценарий использования примерно таков:
HAL, почуяв устройство с подходящей файловой системой, кидает броадкаст сообщение, о том, что-де, обнаружен FAT или там NTFS или еще какой ISO9660 позорный, требуется указать, как его монтировать. Соответствующий _пользовательский_ процесс, запущенный при старте сеанса, сверяется с какой-либо своей настройкой (например, получает значение LC_CTYPE, как вариант или еще что) и отвечает HAL'у, что-де так и так, предпочитаемая локаль пользователя такая-то и такая-то, использовать такой-то и такой-то чарсет для конвертации данных.
(from LAV: пока принцип не очень жизнеспособен, потому что HAL нападёт на первого попавшегося пользователя)
DenisSmirnov /25.02.2005 15:31/Думаю речь должна идти о пользователе, коий последний обращался к консоли
Алексей Морозов:
. /etc/sysconfig/i18n
: ${SYSFONTACM:=koi8-r}
: ${SYSMOUNTCHARSET:=$SYSFONTACM}
echo $SYSMOUNTCHARSET
http://lists.altlinux.ru/pipermail/devel/2005-February/017892.html
Только нужно учитывать, что рецепт, приведенные там не вполне корректен. Во-первых, нужно проверять на наличие файла /etc/hal/fdi/95userpolicy/system_charset.fdi перед его перезаписью. Во-вторых, формируемый .fdi, боюсь, не вполне корректен, требуется еще некоторый пролог и эпилог. Ну, и в третьих, Антон до сих пор не перенес соответствующие настройки
из /usr/share/hal в /etc/hal. Нужно только помнить, что «системные» настройки, которых там большинство лучше по-прежнему оставлять в /usr, т.к. по размеру они большие, а править их все равно не следует. А вот подкаталог 95userpolicy – явный кандидат в /etc.
Да, по поводу mount — есть ещё и libfstype, написаная rider@
Она умеет понимать LABEL на reiserfs разделах (в отличии от mount) и много других вкусных вещей.
У меня есть мнение что пора mount переписывать целиком.
Слишком много недостатков накопилось.
Заодно iocharset надо брать из текущей локали (одно это уже здорово облегчит жизнь).
Для получения iocharset используется библиотека libnatspec, в её каталоге examples имеется соотв. патч для mount.
А rider IMHO неправ в том, что написав библиотеку, не подключил её к mount.
Там не подключать надо, там переделывать логику mount надо. Полностью удаляя весь код автоопределения типа раздела и его параметров, и заменяя на вызовы libfstype. rider свой код писал отнюдь не для mount, и ему просто не до него.
А в ALT уже столько новой функциональности, которую следует учитывать mount, что его действительно пора переписывать.
А этот соответствующий патч приложен в ALT?
Совершенно верно, но чтобы переделать логику и обновить mount, надо
1. Сформулировать, как надо
2. Переписать (и лучше сообщаясь с международной общественностью)
3. apt-cache search по слову fstype не находит libfstype
Соответствующий патч пока не приложен, потому что я так и не понял реакцию на него. Да и библиотека libnatspec последней версии
ещё не появилась в Сизифе. Думаю через bugzilla действовать?
Вы наверное читали обсуждение в devel по поводу нужности какой-либо логики в mount :)
Опаньки, кажись rider@ всё в libhw положил
Обсуждение уже не помню.
Так как libhw потихоньку входит в базовую систему (и это правильно), то mount можно к нему приучать.
По поводу /etc/fstab.d я уже все уши rider'у прожужжал. Он скоро озвереет, и на слово 'fstype.d' будет грязно материться и кидаться тяжёлыми предметами :) А так как теперь правку fstab свалили на HAL, то теперь и rider'у всё пофиг.
Некому mount переписывать.
А с международной общественностью пока libhw существует только в Сизифе об этом разговаривать рано.
Хорошо, я проведу ревизию libhw
Посмотрю в mount на предмет:
Проверю работу с /etc/mtab – ссылкой на /proc/mounts
А libhw так и будет только в Сизифе существовать, нет?
Будет только в Сизифе до тех пор, пока кто-нибудь не захочет её к себе утащить.
Вот только кто? Разве что Debian'овцы в начале. Остальные в kudzu вроде играются. Хотя привлечь внимание можно.
С ссылкой /etc/mtab на /proc/mounts всё прекрасно работает, за исключением mount --bind.
По поводу iocharset — есть смысл посмотреть на код, использующийся в juliet, vfat, ntfs и jfs. В каждой из них есть соответствующий код для поддержки iocharset. Возможно есть смысл найти общие участки, и вынести их в некий общий модуль, на использование которого пропатчить остальные FS.
1. Со ссылкой на /proc/mounts всё работает, в том числе и --bind, но не освобождаются loop-устройства.
2. Я детально рассматривал вариант с iocharset и сравнивал код, но решил, что лучше исправить mount -> это позволит не патчить ядро, это важно, поскольку усложняет задачу. А остальным FS это не поможет, потому что в них нет указания кодировки.
В FAT (не vfat) тоже нет указания кодировки. Однако всё работает. Потому что опциями монтирования можно указать и кодировку внешниюю и внутреннюю.
А то что можно сделать в mount, естественно надо делать в mount. Я имел в виду встраивание самой перекодировки в ext3, например. Чтобы если мне принесли хард с koi8-r, а у меня cp1251, я мог нормально видеть русские буквы.
Я считаю что это должно быть решено отдельным средством, через unionfs или модуль для fuse, позволяющий монтировать с перекодированием. По поводу того, как это может выглядеть, хорошо бы написать статью. Кстати, для fuse можно за полдня такое средство написать.
Просто этот код уже есть для juliet, vfat, jfs. Только разный.
Поэтому есть смысл вынести его за пределы этих FS, и использовать в других. Как вынесли из ext3 код для журналирования.
Модуль для fuse это хороший вариант в том смысле, что более надёжный. Я бы однозначно пропагандировал лишь его, если бы не факт уже наличия в ядре нужного кода, который осталось лишь использовать.
Ну и вопрос с производительностью туда же. Будем ли мы /usr через fuse монтировать? А можно ли иметь русские имена файлов на /usr? А я хочу русские имена команд иногда делать ;)
Код для juliet, vfat достаточно специфичен. Вот jfs – это да, должно быть так же и для остальных.
Там Unicode оказывается внутри, и CONFIG_NLS_DEFAULT по умолчанию для перекодировки.
libnatspec указывает нужный параметр iocharset автоматом.
Может перейти на jfs для переносных дисков ? :)
Модуль для subfs – это как инструмент частного решения проблем. Производительность – да, страдает.
/usr монтировать не будем. Русские названия файлов в rpm-пакетах – только после перехода на utf8.
juliet специфичен только тем, что внутри всегда уникод.
А FAT чем специфичен? Там точно так же кодировка внутри и снаружи может быть разная.
JFS — давить. Это единственное поделие IBM, к которому я не питаю никаких позитивных эмоций. Нафиг он не нужен никому. Из него только код полезный брать есть смысл :)
Насчёт fuse — в любом случае соглашусь, что подобный модуль будет полезен.
Уважаемый с адреса 85.115.231.129, ваши восторги Su Se? понимаю, но не соблаговолите ли показать
unzip -l на zip-архив с русскими именами файлов внутри, сделанный в Windows? А также может посмотрите на
него в ark?
ничем не лучше сп1251. Хотя бы то, что кои8 выживает при потере 8го бита – это весьма важная фича