Кодировка имен файлов в архивах zip
Довольно часто при открытии под Линуксом архивов, содержащих файлы и директории с кириллическими (и вообще любыми не-ASCII) названиями, обнаруживается, что имена файлов в них в неправильной кодировке. Если такой архив распаковать на диск, файлы на диске могут получиться с нечитаемыми названиями.
Происходит это потому, что в разных файловых системах имена файлов хранятся в разных кодировках, да ещё операционные системы работают с ними по-разному, а большинство архивных форматов не предусматривает указания кодировки: какая была при упаковке, такая и будет. Проще говоря, по историческим причинам в кодировках имён файлов в архивах царит кавардак.
Проблема чаще всего возникает с файлами формата ZIP, упакованными под Windows (вообще говоря, существует алгоритм правильного определения кодировок для таких архивов, но он мало где поддерживается). Собственно, форматы TAR, GZIP, BZIP2 и многие другие тоже этому подвержены, но они чаще всего создаются под Линуксом или на других POSIX-совместимых платформах, а там сейчас почти всегда одна и та же кодировка — UTF-8, поэтому проблема не проявляется.
Эта проблема касается исключительно имён файлов и директорий. Содержимого файлов это никак не касается. Естественно, если в архиве есть текстовый файл в неизвестной кодировке, вам придётся её подбирать в текстовом редакторе, но это уже совсем другая история.
Если надо распаковать такой архив, то решение очень простое: надо указать архиватору, в какой кодировке там имена файлов. Проблема в том, что распространённые архиваторы с графическим интерфейсом такой опции не имеют, программы для командной строки обычно тоже (в лучшем случае она глубоко спрятана в документации). Поэтому приводим советы, как именно нужно поступать.
Что касается самой кодировки, то стоит ожидать либо UTF-8, либо CP866, либо (редко) CP1251.
Разархиваторы, которые просто работают
far2l (linux порт Far Manager) выбирает кодировку не-юникодных архивов по системной локали — "сжатые папки" в Windows ведут себя точно также. ppa
The Unarchiver (в дистрибутивах - пакеты unar, unarchiver) умеет угадывать кодировку статистическими методами
unar file.zip
bsdtar (из состава libarchive) умеет распаковывать zip-файлы и преобразует кодировку имен на лету
bsdtar --option hdrcharset=cp866 -xf file.zip
Рецепт для Ubuntu
Добавляем репозиторий с исправленной версией архиваторов:
sudo add-apt-repository ppa:frol/zip-i18n
Обновляем репозитории и пакеты:
sudo apt-get update sudo apt-get upgrade
Далее устанавливаем следующие пакеты:
sudo apt-get install p7zip p7zip-full
Теперь названия файлов в архивах будут отображаться в правильной кодировке.
Рецепт для Gentoo
После пересборки zip и unzip с USE-флагом natspec всё работает само собой. В любительском оверлее rusxmms доступен пакет p7zip с графическим интерфейсом для архиватора 7-Zip, в котором также поправлена кодировка. Для p7zip необходимо включить USE-флах rcc, который используется также в некоторых других пакетах данного оверлея, например id3tag и mpg123.
Рецепт для Fedora
Можно позаимствовать патчи unzip и libnatspec у проекта RussianFedora:
Рецепт для Archlinux
Установите пакет unzip-iconv с AUR:
yaourt -S unzip-iconv
Рецепт для openSUSE
#zypper in unzip-rcc
Универсальные решения
Актуальны для любого дистрибутива
Для терминала
ls | iconv -f Latin1 -t cp850 | iconv -f cp866
unzip file.zip -d directory-name cd directory-name convmv -f cp866 -t utf8 * # удостоверяемся, что всё в порядке convmv --notest -f cp866 -t utf8 * # вместо cp866 может понадобиться cp1251 или даже koi8-r
Для Gnome 2
- Ставим fuse-zip
- Создаём директорию ~/.ZIP
- Пишем скрипт:
#! /bin/bash fusermount -u ~/.ZIP fuse-zip "$1" .ZIP -omodules=iconv,from_code=CP866,to_code=UTF8 nautilus ~/.ZIP xrefresh -white
- Делаем исполняемым и помещаем например если стоит gnome в ~/.gnome2/nautilus-scripts
- Назначаем открывать ZIP-архивы с помощью этого скрипта
Как самому упаковывать файлы, чтобы не было проблем
Проблем не будет, если все имена файлов и директорий в архиве состоят исключительно из латинских букв, цифр, пробелов и базовой пунктуации, кроме слэша (/) — слэш в именах файлов под Линуксом недопустим. Если архив будут открывать под Windows, там запрещённых символов больше: <, >, :, ", /, \, |, ? и * [1]. Но их и под Линуксом не рекомендуется использовать в именах файлов, потому что в командной строке все эти символы имеют специальное значение.
А также проблем не будет с форматом 7z (архиватор p7zip для Линукс/POSIX, 7-Zip для Windows), ни под Линуксом, ни под другими системами: архиватор при упаковке автоматически перекодирует все имена файлов в UTF-8, а при распаковке перекодирует их в кодировку системной локали. Формат полностью свободный и с хорошим сжатием, поэтому им и рекомендуется пользоваться.
Обычно не бывает проблем и с популярным форматом RAR, так как там имена файлов кодируются всегда в UTF-16. Но, во-первых, он проприетарный: свободные архиваторы его более-менее поддерживают, но с некоторыми версиями формата не справляются. Во-вторых, поступают сообщения, что некоторые архиваторы для Линукса всё-таки и при работе с RAR запарывают кодировку. Рекомендуется пользоваться 7z.
Стоит отметить, что программа zip от Info-ZIP, использующаяся в большинстве дистрибутивов, с версии 3.0 при создании архивов сохраняет имена файлов одновременно в двух кодировках: в той, какая есть, и в UTF-8. Такой архив можно будет распаковать без проблем, а совместимость со старыми версиями архиваторов при этом не нарушается. Но это никак не помогает при распаковке архивов, созданных другими программами. На самом деле, даже спецификация формата ZIP включает пункт о том, что имена файлов должны кодироваться либо в CP437, либо в UTF-8, но разработчики архиваторов часто игнорируют этот пункт.