Мы используем rsync
для передачи некоторых (миллионов) файлов с сервера Windows (NTFS / CYGWIN) на сервер Linux (RHEL). Мы хотели бы, чтобы все имена файлов и каталогов в поле Linux были строчными.
Есть ли способ сделать rsync
автоматически преобразовывать все имена файлов и каталогов в нижний регистр? Например, предположим, что в исходной файловой системе был файл с именем:
/foo/BAR.gziP
Rsync создаст (в целевой системе)
/foo/bar.gzip
Очевидно, что NTFS - файловая система без учета регистра, конфликтов быть не может ...
В случае отсутствия rsync
вариант, есть ли улучшенная сборка или какой-то другой способ добиться такого эффекта? Возможно, вариант монтирования на CYGWIN? Возможно, аналогичный вариант монтирования в Linux?
Его RHEL, если это имеет значение.
Не самое элегантное решение, но вы можете использовать LD_PRELOAD, чтобы переопределить соответствующие системные вызовы и перевести все в нижний регистр. Я подумал, что это весело, поэтому сделал небольшое доказательство концепции и ...
> ls in out
in:
CyltApJik keumyomDu LidusIcweo spydjiPa SycsEyror tusUngEg
out:
> rsync -av in/ --rsync-path='env LD_PRELOAD=$PWD/lowercase.so rsync' localhost:out/
sending incremental file list
./
CyltApJik
LidusIcweo
SycsEyror
keumyomDu
spydjiPa
tusUngEg
sent 372 bytes received 129 bytes 1002.00 bytes/sec
total size is 0 speedup is 0.00
> ls out
cyltapjik keumyomdu lidusicweo spydjipa sycseyror tusungeg
И вот образец, который может занять несколько итераций, чтобы стать достаточно хорошим, чтобы синхронизировать все это.
> cat lowercase.c
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#define __USE_GNU
#include <dlfcn.h>
static int (*real_lstat) (const char *, struct stat *) = NULL;
static int (*real_rename)(const char *, const char *) = NULL;
char * lowered(const char * string)
{
char * low = strndup(string, 2048);
char * c;
if (low == NULL) return NULL;
for (c = low; *c; c++) {
*c = tolower(*c);
}
return low;
}
int lstat(const char * path, struct stat * buf)
{
int ret = 0;
if (real_lstat == NULL) {
real_lstat = dlsym(RTLD_NEXT, "lstat");
}
ret = real_lstat(path, buf);
if (ret == 0) return ret;
ret = real_lstat(lowered(path), buf);
return ret;
}
int rename (__const char *__old, __const char *__new)
{
if (real_rename == NULL) {
real_rename = dlsym(RTLD_NEXT, "rename");
}
return real_rename(__old, lowered(__new));
}
> gcc -ldl -fPIC -shared -o lowercase.so lowercase.c
Вы можете смонтировать файловую систему без учета регистра. смотреть на эта почта.
Также на этой странице предлагается создать образ диска типа FAT32
и монтируем его. Созданный файл fs будет нечувствителен к регистру, как и любой раздел Windows.
Использование такого решения избавит от необходимости преобразовывать все эти миллионы файлов в нижний регистр.
Вы можете изменить регистр имен файлов на целевом сервере. после файл rsync. Я бы не стал пытаться делать это в середине передачи (на случай, если вам нужно перезапустить копию). Что касается внесения изменений на стороне Linux, вам необходимо определить, есть ли какие-либо конфликты. Вам также нужно будет определить, нужно ли вам изменить регистр имен каталогов. Все имена будут уникальными? Если да, то соответствующий find
сценарий в сочетании с tr
или rename
команда могла бы сделать работу ...
# Examples - Don't run directly
`rename 'y/A-Z/a-z/' *` # would change case on files within a directory.