rsync apenas diretórios ausentes

2

Existe uma maneira de dizer ao rsync para sincronizar somente os diretórios de origem que estão faltando em um destino (diretórios inteiros, não apenas qualquer arquivo ausente)?

Considerando S como o conjunto de diretórios de origem e D do conjunto de diretórios de destino, desejo:

  • copie todo o diretório s in S if s não em D .
  • ignore totalmente o diretório s (indep. dos arquivos que ele contém) se s in D .

Claro que é possível listar os diretórios em ambos os lados, rsync da lista do destino, fazer alguns perl e gerar uma lista de todos os diretórios que precisam ser copiados, mas seria melhor se fosse possível com apenas uma invocação de rsync .

Por exemplo, se a origem e o destino estiverem no mesmo servidor, pode-se fazer:

src=/some/where
dst=/else/where
cd /tmp
(cd $src; find . -type d) | sort > a
(cd $dst; find . -type d) | sort > b
comm -23 a b | perl -e 'L: while(<>) {chomp; $p=$_; while ($p=~s,/[^/]+$,,) { next L if $n{$p}; } $n{$_}++; s,^./,/,; print "$_/***\n"}' > tocopy
rsync -vmazn --include-from tocopy --exclude '*' $src/ $dst/

(sem o -n se for real).

PS: note que o perl "one-liner" acima (mais ou menos) retira os subdiretórios dos dirs que nós decidimos copiar (já que esses subdiretórios são incluídos na cópia de seus pais). Essa receita acaba com o conjunto mínimo de dirs para copiar.

    
por Pierre D 12.09.2014 / 23:58

1 resposta

1

O que você quiser, não consigo pensar em uma maneira de fazer isso apenas com o rsync.

Se você realmente deseja ignorar completamente os diretórios que existem no lado do destino, o teste não é recursivo, apenas o diretório ou diretórios de nível superior são importantes. Para cada argumento a ser copiado ( dirN in rsync --flag-that-you-hope-exists dir1 dir2 dir3 destination/ ), o diretório existe no lado de destino e não há nada para fazer, ou o diretório de origem não existe e você deseja copiá-lo inteiro.

cd /path/to/source
for x in dir1 dir2 dir3; do
  [ -e "/path/to/target/$x" ] || cp -Rp -- "$x" /path/to/target/
done

Se você realmente quiser recorrer a diretórios que existem no lado de destino e copiar somente arquivos quando um diretório estiver faltando, aqui está um método usando find para percorrer o diretório de origem e verificar cada diretório de destino correspondente.

cd /path/to/source
find . -type d -exec sh -c '
  if [ -e "$0/$1" ]; then exit 0; fi
  cp -Rp -- "$1" "$0/$1"
  exit 1
' /path/to/target {} \; -prune

Se a origem ou o destino for remoto, monte-o com SSHFS .

    
por 14.09.2014 / 04:00

Tags