Вопрос или проблема
Я хотел бы локально прикрепить объем NTFS к своему компьютеру под управлением Unix (Ubuntu) и скопировать (реплицировать) некоторые директории Unix на него, используя rsync, так, чтобы результат был читаем под Windows.
Меня не интересует владение и разрешения. Было бы хорошо, если бы даты модификации сохранялись. Мне нужны только директории и файлы (символические ссылки тоже было бы неплохо; но если их нельзя скопировать, это не проблема).
Две очевидные проблемы: чувствительность к регистру и символы, которые являются запрещенными в именах файлов Windows. Например, в Linux я могу иметь два файла “a” и “A”; я могу скопировать их на объем NTFS, но в Windows я смогу получить доступ (возможно?) только к одному из них. Но я готов игнорировать эту проблему. Меня интересуют запрещенные символы в именах файлов Windows, которые это <,>,:,”,/,\,|,?, и * (на самом деле, также ascii 0-31, но меня это не беспокоит. Возможно, также могут быть проблемы с файлами, заканчивающимися на “.”).
Я хотел бы, чтобы rsync автоматически “переименовывал”, например, файл с именем “a:” в, скажем, a(COLON), чтобы в итоге получить законное имя (и, в идеале, преобразовывать a(COLON) обратно в a:)
Можно ли сделать так, чтобы rsync автоматически переименовывал файлы, чтобы избежать символов, запрещенных в Windows?
- Насколько я понимаю, rsync может использовать iconv для выполнения таких задач; существует ли стандартный модуль iconv для имен файлов Windows? (Я кратко смотрел в программирование собственного модуля gconv, но, не имея знаний по C, это кажется слишком сложным).
- Мне сказали, что rdiff-backup может выполнять некоторые такие преобразования, но на домашней странице только упоминается о том, что что-то делается “автоматически”, и я не уверен, вызовет ли локально смонтированный объем NTFS надежное переименование?
- Я знаю, что есть fuse-posixovl, но это кажется излишним для моей цели, и также, похоже, это плохо документировано (какие символы будут преобразованы каким образом? Будут ли все имена файлов сокращены до 8.3 или что-то еще? Могу ли я избежать дополнительных файлов, содержащих информацию о владельцах/разрешениях, которая мне не нужна, и т.д.).
- Я осведомлен о том, что могу избежать всех этих проблем, используя, например, файл tar; но это не то, что я хочу. (В частности, я хотел бы в Windows дополнительно реплицировать с объема NTFS на другой резервный раздел, копируя только измененные файлы)
- Я знаю о опции “windows_names” при монтировании NTFS; но это предотвратит создание запрещенных файлов, а не переименует их.
Обновление: Поскольку, кажется, мой вопрос был не совсем понятен, позвольте привести более явный пример: Например, WINDOWS-1251 мне не подходит. iconv -f utf-8 -t WINDOWS-1251//TRANSLIT
преобразует
123 abc ABC äö &:<!|
в
123 abc ABC ao &:<!|
Мне нужна кодовая страница, windows-файлы, скажем (которая не существует), которая преобразует строку в что-то вроде
123 abc ABC äö &(COLON)(LT)!(PIPE)
Обновление 2: Я теперь сдался и переименовал запрещенные файлы “вручную” (т.е. с помощью скрипта). С тех пор, каждый раз перед запуском rsync, я запускаю скрипт, который проверяет, существуют ли запрещенные имена файлов (но не переименовывает автоматически); я просто использую
# находим объекты, содержащие запрещенные символы
find $MYDIR -regex '.*/[^/]*[<>:*"\\|?][^/]*'
# находим объекты, заканчивающиеся точкой (предположительно плохо для windows)
find $MYDIR -regex '.*\.'
# находим объекты, идентичные независимо от регистра
find $MYDIR -print0 | sort -z | uniq -diz | tr '\0' '\n'
(последняя строка взята из поиска дубликатов имен файлов независимо от регистра)
Прагматичным решением было бы воспроизвести исходные директории с желаемыми преобразованными именами файлов локально, используя жесткие ссылки на оригинальные файлы, а затем rsync эту копию как есть на файловую систему ntfs.
Например, этот демонстрационный скрипт на perl дублирует иерархию /tmp/a/
в /tmp/b/
и кодирует (с помощью %
и 2 шестнадцатеричных цифр) нежелательные символы, так что file:b
становится file%3ab
(жесткая ссылка), а директория %b<ha>
становится директорией %25b%3cha%3e
и так далее:
#!/usr/bin/perl
use strict;
use File::Find;
my $startdir="/tmp/a";
my $copydir="/tmp/b";
sub handlefile{
my $name = substr($File::Find::name,1);
my $oldname = $startdir.$name;
$name =~ s/([;, \t+%&<>:\"\\|?*])/sprintf('%%%02x',ord($1))/ge;
$name = $copydir.$name;
printf "from %s to %s\n",$oldname,$name;
if(!-l and -d){ mkdir($name) or die $!; }
else{ link($oldname,$name) or die $!; }
}
chdir($startdir) or die;
find(\&handlefile, '.');
Вы можете затем rsync /tmp/b
на ваш ntfs. Это всего лишь демонстрация и требует доработки для учета unicode и других ограничений ntfs, таких как максимальная длина имени файла. Вы также можете проверить наличие конфликтов между строчными и прописными буквами и использовать ваше предпочтительное кодирование (:
на COLON
и так далее). Вы можете сделать еще один проход, чтобы исправить временные метки на директориях. Если у вас нет миллионов файлов, работа, необходимая для создания этой копии структуры каталогов с жесткими ссылками на файлы, не должна быть такой обременительной.
Ответ или решение
Учитывая ваш запрос о том, как использовать модуль iconv с rsync для копирования данных на локально смонтированный NTFS-том с учетом недопустимых для Windows имен файлов, важно рассмотреть несколько аспектов, чтобы обеспечить успешное решение вашей задачи.
Введение в проблему
Системы Linux и Windows имеют разные подходы к именованию файлов. В частности, Windows имеет набор символов, которые считаются недопустимыми при создании имен файлов, среди которых: <
, >
, :
, "
, /
, \
, |
, ?
, *
и символы ASCII с кодом от 0 до 31. Это может вызвать проблемы при копировании файлов и директорий с Linux на NTFS.
Использование rsync с модулем iconv
-
Модуль iconv: Стандартного модуля iconv для обработки недопустимых имен файлов в контексте Windows не существует. Вы не сможете найти готовый кодек, который готов бы автоматически преобразовывать недопустимые символы в допустимые при использовании rsync. Однако, вы можете самостоятельно написать скрипт, который предварительно преобразует имена файлов в необходимый вам формат.
-
Преобразование имен: Для замены недопустимых символов вы можете использовать различные подходы. Например, вы можете создать скрипт на Perl, Python или даже на Bash, который будет проходить по файловой системе, находить недопустимые символы и заменять их на допустимые. Например,
a:
может быть преобразовано вa(COLON)
. -
Ракурс к rsync: Используйте rsync для синхронизации с NTFS томом после того, как вы создали предварительно обработанные копии файлов с допустимыми именами. Например:
rsync -av --progress /path/to/processed/files /mnt/ntfs/
Практическое решение
В качестве примера, вот базовый Perl-скрипт, который рекурсивно дублирует директорию, заменяя недопустимые символы.
#!/usr/bin/perl
use strict;
use warnings;
use File::Find;
my $src_dir = "/path/to/source";
my $dest_dir = "/path/to/destination";
sub handle_files {
my $name = substr($File::Find::name, 1);
my $oldname = $src_dir . $name;
$name =~ s/[<>:"\/\\|?*]/sprintf("(%s)", $&)/ge; # Замена недопустимых символов
my $newname = $dest_dir . $name;
if (-d $oldname) {
mkdir($newname) or die $!;
} else {
link($oldname, $newname) or die $!;
}
}
chdir($src_dir) or die;
find(\&handle_files, '.');
Альтернативные подходы
-
Использование
fuse-posixovl
: Если вы хотите более автоматизированное решение, возможно, стоит рассмотреть использованиеfuse-posixovl
, хотя это может быть избыточным для вашей задачи. Однако его документация может быть не вполне понятной и требует знаний о том, как он обрабатывает имена файлов. -
Ручная проверка: Как упомянуто вами, вы можете выполнять ручную проверку на недопустимые имена файлов перед копированием. Это может занимать больше времени, но позволяет вам иметь полный контроль над процессом.
-
Пакетные преобразования: Вы можете создавать пакетные сценарии для выполнения всех замен перед каждой операцией rsync.
Заключение
На данный момент нет универсального или автоматического решения для обработки недопустимых символов имен файлов при копировании данных с Linux на NTFS с помощью rsync. Однако, создание предварительно обработанных копий с использованием пользовательских скриптов, как указано выше, позволит вам достичь нужного результата и избежать проблем с совместимостью в Windows. Если вам необходима дополнительная помощь в реализации, буду рад предложить более подробные инструкции по каждой части процесса.