iconv module (para usar com o rsync) para evitar nomes de arquivos ilegais do Windows na partição local do NTFS

1

Gostaria de anexar localmente um volume NTFS à minha máquina unix (Ubuntu), e copiar (replicar) alguns diretórios unix para ele, usando o rsync, de uma forma que o resultado seja legível no Windows.

Eu não me importo com propriedade e permissões. Seria bom se as datas de modificação fossem preservadas. Eu só preciso de diretórios e arquivos (links simbólicos também seriam bons; mas não um problema se eles não puderem ser copiados).

Dois problemas óbvios são: case (in) sensitivity e caracteres que são ilegais em nomes de arquivos do Windows. Por exemplo, no Linux eu posso ter dois arquivos "a" e "A"; Eu posso copiá-los para o volume NTFS, mas no Windows eu será capaz de acessar (no máximo?) Um deles. Mas estou feliz em ignorar esse problema. O que me interessa são caracteres ilegais em nomes de arquivos do Windows, que são <, & gt ;,: ", /, \, |,? E * (bem, na verdade também ascii 0-31, mas eu não me preocupo com Também pode haver problemas com arquivos terminados em "."?).

Gostaria que o rsync automaticamente "renomeie", por exemplo, um arquivo chamado "a:" para, digamos um (COLON), para acabar com um nome legal (e, idealmente, traduzir um (COLON) de volta para a:)

É possível que o rsync renomeie automaticamente os arquivos para evitar caracteres proibidos no Windows?

  • Até onde eu sei, o rsync pode usar o iconv para executar tais tarefas; Existe um módulo iconv padrão para nomes de arquivos do windows? (Eu olhei brevemente para programar um módulo gconv próprio, mas faltando conhecimento C isso parece muito complicado).
  • Foi-me dito que o rdiff-backup pode fazer algumas conversões como essa, mas a página inicial menciona algo sendo feito "automaticamente", e não tenho certeza se um NTFS vomlume montado localmente uma renomeação de maneira confiável?
  • Estou ciente de que existe fuse-posixovl , mas isso parece um exagero para o meu propósito, e também não parece estar bem documentado (quais personagens serão traduzidos de que maneira? Todos os nomes de arquivos serão truncados para 8.3 ou qualquer outra coisa? Posso evitar os arquivos adicionais que transportam informações de proprietário / permissão, o que eu não precisarei, etc etc.)
  • Estou ciente de que posso evitar todos esses problemas usando, por exemplo, um arquivo tar ; mas isso não é o que eu quero. (Em particular, eu gostaria que no Windows replicasse ainda mais do volume NTFS para outra partição de backup, copiando apenas os arquivos alterados)
  • Estou ciente da opção " windows_names " ao montar o NTFS; mas isso impedirá a criação de arquivos ofensivos, não os renomeie.

Atualização: Como parece que minha pergunta não estava clara, deixe-me dar um exemplo mais explícito: Por exemplo, o WINDOWS-1251 não é útil para mim. %código% transforma

123 abc ABC äö &:<!|

em

123 abc ABC ao &:<!|

Eu precisaria de uma página de código, windows-filenams, que digam (que não existe), que transforma a string em algo como

123 abc ABC äö &(COLON)(LT)!(PIPE)

Atualização 2: agora desisti e renomei os arquivos ofensivos '' manualmente '' (por exemplo, por script). De agora em diante, toda vez que executar o rsync, eu executo um script que verifica se existem nomes de arquivos ofensivos (mas não trata automaticamente de renomear nada); Eu apenas uso

# find stuff containing forbidden chars
find $MYDIR -regex '.*/[^/]*[<>:*"\|?][^/]*'
# find stuff containing dot as last character (supposedly bad for windows)
find $MYDIR -regex '.*\.'
# find stuff that is identical case insensitive
find $MYDIR -print0 | sort -z | uniq -diz | tr '
123 abc ABC äö &:<!|
' '\n'

(a última linha é de pesquisa sem diferenciação de maiúsculas e minúsculas nomes de arquivos )

    
por Jakob 07.02.2017 / 15:53

1 resposta

0

Uma solução pragmática seria reproduzir os diretórios de origem com os nomes de arquivos convertidos desejados localmente, usando hard links para os arquivos originais, e então rsync esta cópia como está para o sistema de arquivos ntfs.

Por exemplo, essa demonstração de script perl duplica a hierarquia /tmp/a/ em /tmp/b/ e url-codifica (com % e 2 dígitos hexadecimais) os caracteres indesejáveis, então file:b se torna file%3ab (um link físico) e o diretório %b<ha> se torna o diretório %25b%3cha%3e e assim por diante:

#!/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, '.');

Você pode então rsync /tmp/b para o seu ntfs. Esta é apenas uma demonstração, e precisa de trabalho para unicode e outras limitações do ntfs como tamanho máximo do nome do arquivo. Você também pode verificar se há conflitos entre maiúsculas e minúsculas e usar sua codificação preferida ( : to COLON e assim por diante). Você poderia fazer uma segunda passagem para corrigir os registros de data e hora nos diretórios. A menos que você tenha milhões de arquivos, o trabalho necessário para criar essa cópia da estrutura de diretórios, com hard links para os arquivos, não deve ser tão oneroso.

    
por 08.02.2017 / 18:10