Tar и «неправильная» кодировка имен файлов
Возникла задача более-менее регулярного переноса большого объема мелких файлов с одного компьютера на другой. Копирование напрямую хоть по сети, хоть через внешний накопитель занимает неприличное время. Желательно эту подборку как-то упаковать. Можно даже совсем без сжатия.
- Лирическое отступление
- Подобная задача хорошо знакома тем, кто регулярно выполняет резервное копирование, но малознакома большинству средних пользователей, в том числе и мне. Однако ж бывают случаи и для нас, не-админов. Во-первых, я пользуюсь расширением ScrapBook для браузера Mozilla FireFox и регулярно переношу накопленную полезную информацию из сети на те компьютеры, которыми пользуюсь при отсутствии сети. Это ноутбук, который со мной обычно там, где интернетов нет в принципе, а раньше и комп на работе, где интернету нету по велению свыше, впрочем, теперь туда с флэшками нельзя. Во-вторых, это кэш замечательной программы SAS Планета, для тех же условий, например, на ноутбуке в путешествиях.
Для такой цели (с учетом некритичности сжатия данных) трудно придумать что-нибудь лучше инструмента, специально для этого дела разработанного — tar. На больших наборах мелких файлов он уверенно обгоняет предпочитаемый мной в виндах 7zip без сжатия. Только что загнал в два архива — tar и 7z — папку с кучей мелочи 1,2 Гб: 6:29 против 15:49 (минут:секунд). Причем в подборке gnuwin32 имеется реализация tar под винду, помимо кучи других вкусностей, которые в Linux есть «из коробки».
Однако tar имеет одну неприятную особенность. Ежели, к примеру, запаковать в 7zip кучку файлов с кириллическими именами в винде, они нормально, по-русски, распакуются в Linux. И, что характерно, наоборот. А то, что упаковано в tar, будет распаковано в другой системе с непонятным набором символов вместо имен. По крайней мере, если винда все еще XP.
Более того, если загнать в tar упомянутую кучку в XP, то она и в XP распакуется с неправильными именами.
- Лирическое отступление
- Непосредственно для данных ScrapBook и тайлов SAS Планеты это не проблема, там нет кириллицы в именах файлов. Однако при экспорте пачки файлов из ScrapBook они сохраняются в папках, у которых имена совпадают с заголовком страницы, а это может быть и кириллица. Да и вообще, случаи разные бывают… Если есть проблема, хотелось бы иметь наготове способ решения.
Поиском по сети наткнулся на блог, автор которого предложил решение, основанное на ответе на superuser.com, а конкретно здесь.
Решение требует Python, он у меня есть, третий. Точнее, 3.3, потому что на одном из компьютеров, которыми я пользуюсь, стоит WinXP, а там версия 3.3 — последнее, что можно установить. На домашней семерке то же самое, чтобы не было путаницы при переносе кода.
Сперва я попробовал запустить предложенный скрипт не думая, просто скопировал код в py-файл и запустил. Ну, конечно, не получилось. Сперва была ошибка, связанная с тем, что в третьем питоне функция print — именно функция и требует скобочек, а потом мне в консоли сказали, что не знают такую фигню, как unicode().
Давненько я не общался с питонами, полез в справку. Что делать с unicode(), я так и не нашел, зато нашел справку по tarfile и обнаружил, что среди аргументов он принимает еще и encoding. И скрипт сразу упростился:
#!/usr/bin/python3
import tarfile
import sys
if len(sys.argv) == 1:
print("usage: %s <tar archive>" % (sys.argv[0]))
sys.exit(0)
arhive_name = sys.argv[1]
archive_encoding = 'cp1251'
#archive_encoding = 'utf-8'
tar = tarfile.open(name=arhive_name, mode='r', bufsize=16*1024, encoding=archive_encoding)
tar.extractall()
tar.close()
Запускается в винде с именем архива в аргументе: python <имя скрипта>.py <имя архива>.tar
.
archive_encoding = 'cp1251'
для распаковки (в винде и линуксе) таров, упакованных в винде, archive_encoding = 'utf-8'
для распаковки в винде упакованных в Linux. Распаковывается с русскими именами файлов.
Попробовал в Linux — тоже работает. Упакованные в Windows тары при открытии, скажем, в mc или распакованные через tar имеют битую кириллическую кодировку, а этим скриптом открываются нормально.
Кстати, если py-скрипт написан в Windows, то для запуска его в Linux нужно не забыть сменить формат файла на юниксовый, в смысле символов конца строки/возврата каретки. GVIM делает это очень просто: :set fileformat=unix
.
Надо сказать, что Archive Manager (кажется, он в Debian Jessi работает архивариусом по умолчанию) открывает tar-архивы с правильной кодировкой, даже запакованные в Windows, а в винде 7zip открывает упакованное под линем тоже нормально. Но tar, даже в питоновом варианте, работает побыстрее, как мне показалось. Честно говоря, тут время я не засекал. Кроме того, 7zip в Windows коряво распаковывает tar-архивы с кириллическими именами, запакованными в этой же системе.
Я понимаю, что под задачу надо подбирать инструмент, требующий минимум извращений и издевательств, но случаи бывают разные. Например, тяжелое наследие прошлого или чужие данные, на подготовку которых уже повлиять нельзя, а использовать надо.