rsync, exclua os arquivos no lado de recebimento que foram excluídos no lado de envio. (Mas não exclua tudo)


9

Eu gostaria de usar o rsync para ...

  • excluir arquivos no lado de recebimento que também foram excluídos no lado de envio
  • exclua outros arquivos que estão no diretório rsynced do lado receptor

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

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

a.txt
b.txt
c.txt

meu diretório remoto que eu 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:

APÓS EXCLUIR LOCAL: local-src contém localmente ...

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:

APÓS DELETE LOCAL: remote-src contém remotamente ...

c.txt
d.txt
README.md

Ou seja, a.txte b.txtestão remotamente apagado bem, mas d.txte README.txtsão deixados sozinhos.

Existe alguma maneira de conseguir isso com o rsync?

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

Digamos que eu tenho um servidor web. Nesse servidor web, eu tenho vários diretórios, digamos que eu tenho um diretório Ae um public_htmldiretório dos quais meu site é veiculado. Digamos que eu tenho algum processo automatizado que produz arquivos no diretório A. Eu gostaria de rsync (ou sincronização usando alguma outra ferramenta) os arquivos gerados ou atualizados em Aao public_htmldiretório, sem excluir outros arquivos arbitrários que podem estar dentro public_html. Eu certamente não quero que o rsync exclua acidentalmente meu site.

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


2
Depois de reler sua pergunta, acho que isso não é possível, rsyncpois não há como saber quais arquivos já estão na pasta remota. Você pode precisar descobrir outra ferramenta.
Spack

O rsync não permitirá que você faça isso, mas se você scp o diretório inteiro toda vez que excluir arquivos, poderá mantê-los sincronizados, não uma solução, apenas uma sugestão.
Aadi Droid

1
Eu acho que você já pensou nisso, mas você não pode simplesmente colocar esses arquivos em um subdiretório (ou em outro lugar) e referenciá-los a partir de public_html? Dessa forma, você tem um diretório que é fácil e explicitamente sincronizado, sem afetar os arquivos em outras partes do sistema de arquivos do servidor da web.
precisa saber é o seguinte

Respostas:


2

O que você quer fazer é razoável, mas usá rsync-lo por conta própria não é. Então a resposta é não .

O motivo é simples: rsyncnã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 o que não. Não sem suporte adicional.

Você deve se perguntar por que gosta de fazer isso rsynce deixar isso mais claro. Existem outros programas librsync1.soque são mais inteligentes.


Com as restrições relaxadas de que você não precisa rsync, você pode dar uma olhada no rdiff-backup :

mkdir a
touch a/xx
touch a/yy
rdiff-backup a b
ls b 

Isto mostra xxe yyestão em b.

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

Isto mostra xxe zzestão em b. rdiff-backuptambém mantém um diretório rdiff-backup-data, bpara que você possa reverter quaisquer alterações; limpe-o regularmente usando os rdiff-backupcomandos (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, bazar, git). Com mercurial, por exemplo, você pode ter um script (eu uso um Makefile para isso), que envia todas as alterações ao servidor e faz uma atualização dos arquivos com check-out por lá, ignora todos os arquivos adicionais que estão no servidor remoto (mas têm não foi colocado 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 fazer:

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

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


Eu posso aceitar que o rsync não fará isso. Mas não concordo que isso seria impossível com o rsync - se o rsync sabe do lado de envio quais arquivos foram excluídos, por que não pode enviar essas informações para o lado de recebimento no diff? Depois de comparar a atualização, não vejo por que o lado receptor não pode simplesmente excluir os arquivos que foram indicados para serem excluídos no diff, sem excluir todo o resto do diretório. A exclusão de todos os outros arquivos inocentes (excluídos na fonte) do diretório parece-me irracional.
Heather Miller

De qualquer forma, a razão pela qual eu preciso disso é a seguinte. Eu tenho um diretório, vamos chamá-lo A, onde algum processo é automatizado e os arquivos são gerados automaticamente lá. Eu tenho um servidor da web e gostaria que os arquivos Acontidos fossem sincronizados no public_htmldiretório do servidor da web, é claro, sem excluir tudo o mais na public_htmlpasta do servidor da web. Se alguém tiver alguma idéia para conseguir isso com outra ferramenta, seria mais que bem-vindo. Vou atualizar minha pergunta para refletir isso.
Heather Miller

Para esclarecer meu primeiro comentário acima, eu deveria ter dito "Não concordo que algo como isso seja impossível com uma ferramenta como o rsync". Intuitivamente, parece que isso não pode ser muito difícil de alcançar (a menos que esteja faltando alguma coisa).
Heather Miller

Hmm, ok. Eu acho que vejo agora - como o rsync pode saber quando algo foi excluído no local-srcdiretório sem ter algum processo observando esse diretório para alterações. Talvez isso fosse difícil.
Heather Miller

@HeatherMiller Como escrevi, seu pedido é razoável, mas rsyncnão é a ferramenta. Por favor, perceber que syncem rsyncvem de sincronização e que não é exatamente o que você quer fazer. No desenvolvimento do rsyncfoco tem sido eficiente (minimizar) a transferência de dados. Outras ferramentas como rdiff-backup(e possível cvsup) usaram suas técnicas para isso, mas foram desenvolvidas com recursos adicionais.
Anthon

1

Eu não acho que isso seja possível sem excluir explicitamente os arquivos no lado de recebimento como parte do comando rsync. Consulte a seção da página de manual do rsync: "REGRAS POR EXTREMIDADE E EXCLUIR".

Sem uma opção de exclusão, as regras por diretório são relevantes apenas no lado do envio, para que você possa excluir os arquivos de mesclagem sem afetar a transferência. Para facilitar, o modificador 'e' adiciona essa exclusão para você, como visto nesses dois comandos equivalentes:

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

No entanto, se você deseja excluir no lado de recebimento E deseja excluir alguns arquivos da exclusão, precisará ter certeza de que o lado de recebimento sabe quais arquivos excluir. A maneira mais fácil é incluir os arquivos de mesclagem por diretório na transferência e usar --delete-after, porque isso garante que o lado receptor receba as mesmas regras de exclusão do lado de envio antes de tentar excluir qualquer coisa:

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

No entanto, se os arquivos de mesclagem não fizerem parte da transferência, você precisará especificar algumas regras de exclusão globais (ou seja, especificadas na linha de comando) ou manter seus próprios arquivos de mesclagem por diretório no diretório lado receptor. Um exemplo do primeiro é este (suponha que os arquivos .rules remotos se excluam):

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

No exemplo acima, o arquivo extra.rules pode afetar os dois lados da transferência, mas (no lado de envio) as regras são subservientes às regras mescladas nos arquivos .rules porque foram especificadas após a regra de mesclagem por diretório.

Em um exemplo final, o lado remoto está excluindo os arquivos de filtro .rsync da transferência, mas queremos usar nossos próprios arquivos de filtro .rsync para controlar o que é excluído no lado de recebimento. Para fazer isso, devemos excluir especificamente os arquivos de mesclagem por diretório (para que eles não sejam excluídos) e, em seguida, colocar regras nos arquivos locais para controlar o que mais não deve ser excluído. Como um destes comandos:

       rsync -av --filter=':e /.rsync-filter' --delete \
           host:src/dir /dest
       rsync -avFF --delete host:src/dir /dest

0

Se eu entendi corretamente, --excludepode 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

Bem não. Não quero listar manualmente todos os arquivos que gostaria de excluir. Eu gostaria que o rsync apenas excluísse os arquivos que eu excluí na fonte - eu não deveria saber na fonte quais outros arquivos possíveis existem no mesmo diretório no destino.
Heather Miller #

0

Eu tenho uma resposta para isso. Eu acho que funciona. E funciona para mim . Primeiro você deve ter rsyncarquivos remotos em arquivos locais. O lado local contém todos os arquivos.

sudo rsync -r -a -v --delete /root@xx.xx.xx.xx:/remote_dir/ /local_dir/

agora no lado local

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

Em seguida, 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 rsyncarquivos locais para o lado remoto. Em seguida, ambos os lados têm os mesmos arquivos.

sudo rsync -r -a -v --delete /local_dir/ root@xx.xx.xx.xx:/remote_dir/

c.txt
d.txt
README.md

arquivos no lado remoto e no lado local (ao usar --delete, ele exclui outros arquivos no lado remoto que não coincidem com o lado local ).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.