rsync, apague os arquivos no lado de recebimento que foram apagados no lado de envio. (Mas não apague tudo)

9

Gostaria de usar o rsync para ...

  • excluir arquivos no lado do destinatário que também foram excluídos no lado do envio
  • não exclui outros arquivos que estão no diretório rsynced no lado do recebimento

Por exemplo, digamos que eu tenha um diretório local-src :

ANTES: local-src localmente contém ...

a.txt
b.txt
c.txt

meu diretório remoto que gostaria de sincronizar com o conteúdo de local-src é chamado remote-src .

ANTES: remote-src contém remotamente ...

a.txt
b.txt
c.txt
d.txt
README.md

Digamos que eu exclua alguns arquivos em local-src :

DEPOIS DE DELETE LOCAL: local-src localmente contém ...

c.txt

Como posso usar o rsync de forma a garantir que os arquivos excluídos na origem também sejam excluídos no destino, mas sem excluir outros arquivos no destino. Por exemplo, eu gostaria de ter o seguinte no destino:

DEPOIS DE DELETE LOCAL: remote-src contém remotamente ...

c.txt
d.txt
README.md

Ou seja, a.txt e b.txt também são excluídos remotamente, mas d.txt e README.txt são deixados em paz.

Existe alguma maneira de conseguir isso com o rsync?

EDITAR: O veredicto parece ser que isso pode ser impossível com o rsync. Fui perguntado por que preciso disso, para ilustrar meu caso de uso:

Digamos que eu tenha um servidor da web. Nesse servidor web, eu tenho um monte de diretórios, digamos que eu tenho um diretório A e um diretório public_html do qual meu site é servido. Digamos que eu tenha algum processo automatizado que produza arquivos no diretório A . Eu gostaria de rsync (ou sincronizar usando alguma outra ferramenta) os arquivos gerados ou atualizado em A para o diretório public_html , sem excluir outros arquivos arbitrários que podem estar dentro de public_html . Eu certamente não quero que o rsync apague acidentalmente meu site.

Se o rsync não é a ferramenta para este trabalho, alguém sabe como posso fazer isso?

    
por Heather Miller 22.05.2013 / 22:09

4 respostas

2

O que você quer fazer é razoável, mas usar rsync para fazer isso sozinho não é. Então a resposta é não .

O motivo é simples: rsync não mantém histórico do que estava em cada diretório e não tem como saber o que precisa ser excluído e quais não. Não sem suporte adicional.

Você deve se perguntar por que gosta de fazer isso com rsync e deixar isso mais claro. Existem outros programas que usam librsync1.so que são mais inteligentes.

Com as restrições relaxadas de que você não precisa de rsync per se, você pode dar uma olhada em rdiff-backup :
mkdir a
touch a/xx
touch a/yy
rdiff-backup a b
ls b 

Isso mostra que xx e yy estão em b .

touch b/zz
rm a/xx
rdiff-backup a b

Isso mostra xx e zz em b . rdiff-backup também mantém um diretório rdiff-backup-data em b para que você possa reverter quaisquer alterações, você deve limpá-la regularmente usando os comandos rdiff-backup . (O exemplo é com arquivos locais para mostrar que dados extras no destino não são excluídos, mas o rdiff-backup também funciona em uma rede).

Outra alternativa é configurar algum sistema de controle de revisão distribuído (mercurial, bazaar, git). Com mercurial, e. você pode ter um script (eu uso um Makefile para isso), que empurra todas as mudanças para o servidor e então faz uma atualização dos arquivos com check-out, ignora quaisquer arquivos adicionais que estão no servidor remoto (mas não foram colocados sob controle de revisão).

No servidor, você faria:

hg init
hg add file_list_excluding_that_should_not_should_be_deleted_if_not_on_client
hg commit -m "initial setup"

No cliente:

hg clone ssh://username@server/dir_to_repository

Agora, se você remover um arquivo no cliente e fizer isso:

hg commit -m "removed file"
ssh username@server "cd dir_to_repository; hg update --clean"

Seu arquivo removido é removido no servidor, mas quaisquer outros dados (não adicionados ao repositório) não são excluídos.

    
por 23.05.2013 / 06:23
1

Eu não acho que isso seja possível sem excluir explicitamente os arquivos no lado do recebimento como parte do comando rsync. Veja a seção da página de manual do rsync: "REGRAS DE PER-DIRETÓRIO E DELETE".

Without a delete option, per-directory rules are only relevant on the sending side, so you can feel free to exclude the merge files themselves without affecting the transfer. To make this easy, the ’e’ modifier adds this exclude for you, as seen in these two equivalent commands:

          rsync -av --filter=': .excl' --exclude=.excl host:src/dir /dest
          rsync -av --filter=':e .excl' host:src/dir /dest

However, if you want to do a delete on the receiving side AND you want some files to be excluded from being deleted, you’ll need to be sure that the receiving side knows what files to exclude. The easiest way is to include the per-directory merge files in the transfer and use --delete-after, because this ensures that the receiving side gets all the same exclude rules as the sending side before it tries to delete anything:

          rsync -avF --delete-after host:src/dir /dest

However, if the merge files are not a part of the transfer, you’ll need to either specify some global exclude rules (i.e. specified on the command line), or you’ll need to maintain your own per-directory merge files on the receiving side. An example of the first is this (assume that the remote .rules files exclude themselves):

   rsync -av --filter=’: .rules’ --filter=’. /my/extra.rules’
      --delete host:src/dir /dest

In the above example the extra.rules file can affect both sides of the transfer, but (on the sending side) the rules are subservient to the rules merged from the .rules files because they were specified after the per-directory merge rule.

In one final example, the remote side is excluding the .rsync-filter files from the transfer, but we want to use our own .rsync-filter files to control what gets deleted on the receiving side. To do this we must specifically exclude the per-directory merge files (so that they don’t get deleted) and then put rules into the local files to control what else should not get deleted. Like one of these commands:

       rsync -av --filter=':e /.rsync-filter' --delete \
           host:src/dir /dest
       rsync -avFF --delete host:src/dir /dest
    
por 23.05.2013 / 01:00
0

Se eu entendi corretamente, o --exclude pode ser o que você está procurando:

$ ls src dst
dst:
a.txt  b.txt  c.txt  d.txt  README.md

src:
c.txt
$ rsync --update --delete --recursive --exclude="d.txt" --exclude="README.md" src/ dst
$ ls src dst
dst:
c.txt  d.txt  README.md

src:
c.txt
    
por 22.05.2013 / 22:44
0

Eu tenho uma resposta para isso. Eu acho que funciona. E funciona para mim . Primeiro você deve ter rsync arquivos remotos para arquivos locais. Então o lado local contém todos os arquivos.

sudo rsync -r -a -v --delete /[email protected]:/remote_dir/ /local_dir/

agora no lado local

a.txt
b.txt
c.txt
d.txt
README.md

Depois, você pode excluir os arquivos ou fazer o que quiser (no lado local). Na sua pergunta, você exclui esses arquivos.

arquivos excluídos

a.txt
b.txt

Depois disso, você pode rsync arquivos locais para o lado remoto.Então os dois lados têm os mesmos arquivos.

sudo rsync -r -a -v --delete /local_dir/ [email protected]:/remote_dir/

c.txt
d.txt
README.md

arquivos no lado remoto e no lado local (usando --delete , exclui outros arquivos no lado remoto que não correspondem ao lado local ).

    
por 03.07.2013 / 07:19

Tags