rsync, supprime les files du côté réception qui ont été supprimés du côté envoi. (Mais ne pas tout supprimer)

Je voudrais utiliser rsync pour …

  • supprimer les files du côté réception qui ont également été supprimés du côté émetteur
  • ne pas supprimer d'autres files qui se trouvent dans le directory rsynced du côté réception

Par exemple, disons que j'ai un directory local-src :

AVANT: local-src contient localement …

 a.txt b.txt c.txt 

mon directory distant que je voudrais synchroniser au contenu de local-src est appelé remote-src .

AVANT: remote-src contient …

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

Disons que je supprime certains files dans local-src :

AFTER LOCAL DELETE: local-src contient localement …

 c.txt 

Comment puis-je utiliser rsync pour que les files supprimés à la source soient également supprimés à la destination, mais sans supprimer d'autres files à la destination. Par exemple, j'aimerais avoir ce qui suit à la destination:

APRES DELETE LOCALE: remote-src contient …

 c.txt d.txt README.md 

Autrement dit, a.txt et b.txt sont également supprimés à distance, mais d.txt et README.txt sont laissés seuls.

Y at-il un moyen d'y parvenir avec rsync?

EDIT: Le verdict semble être que cela pourrait être impossible avec rsync. On m'a demandé pourquoi j'en ai besoin, pour illustrer mon cas d'utilisation:

Disons que j'ai un server web. Sur ce server web, j'ai un tas de directorys, disons que j'ai un directory A et un directory public_html dont mon site est desservi. Disons que j'ai un process automatisé qui produit des files dans le directory A Je voudrais rsync (ou synchroniser en utilisant un autre outil) les files générés ou mis à jour dans A au directory public_html , sans supprimer d'autres files arbitraires qui pourraient être dans public_html . Je ne veux certainement pas rsync supprimer accidentellement mon site.

Si rsync n'est pas l'outil pour ce travail, quelqu'un d'autre sait-il comment je peux le faire?

Ce que vous voulez faire est raisonnable, mais utiliser rsync pour le faire seul ne l'est pas. Donc la réponse est non .

La raison est simple: rsync ne conserve aucun historique de ce qui se trouve dans chaque directory et n'a aucun moyen de savoir ce qui doit être supprimé et ce qui ne l'est pas. Pas sans soutien supplémentaire.

Vous devriez vous requestr pourquoi vous aimez faire cela avec rsync et clarifier cela. Il existe d'autres programmes qui utilisent librsync1.so qui sont plus intelligents.


Avec les contraintes détendues que vous n'avez pas besoin de rsync soi, vous pouvez jeter un oeil à rdiff-backup :

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

Cela montre que xx et yy sont dans b .

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

Cela montre que xx et zz sont dans b . rdiff-backup garde également un directory rdiff-backup-data dans b afin de pouvoir annuler les modifications, vous devriez le purger régulièrement à l' rdiff-backup commands rdiff-backup . (L'exemple est avec des files locaux pour montrer que datatables supplémentaires dans la cible ne sont pas supprimées, mais rdiff-backup fonctionne également sur un réseau).


Une autre alternative consiste à installer un système de contrôle de révision dissortingbué (mercurial, bazar, git). Avec Mercurial par exemple, vous pouvez avoir un script (j'utilise un Makefile pour cela), qui pousse toutes les modifications sur le server, puis fait une mise à jour des files extraits là, ignorer les files supplémentaires qui se trouvent sur le server distant pas été mis sous contrôle de révision).

Sur le server, vous feriez:

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

Sur le client:

 hg clone ssh://username@server/dir_to_repository 

Maintenant, si vous supprimez un file sur le client et que vous le faites:

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

Votre file supprimé est supprimé sur le server, mais aucune autre donnée (non ajoutée au référentiel) n'est supprimée.

Je ne pense pas que cela soit possible sans exclure explicitement les files du côté réception dans le cadre de la command rsync. Reportez-vous à la section de la page man pour rsync: "PER-DIRECTORY RULES AND DELETE".

En l'absence d'une option de suppression, les règles par directory ne sont pertinentes que du côté de l'envoi, vous pouvez donc exclure les files de fusion eux-mêmes sans affecter le transfert. Pour faciliter cela, le modificateur 'e' ajoute cette exclusion pour vous, comme on le voit dans ces deux commands équivalentes:

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

Cependant, si vous souhaitez effacer une partie du côté réception ET que certains files doivent être exclus de la suppression, vous devez vous assurer que la partie récepsortingce connaît les files à exclure. La méthode la plus simple consiste à inclure les files de fusion par directory dans le transfert et à utiliser –delete-after, car cela garantit que le côté réception reçoit les mêmes règles d'exclusion que le côté envoi avant d'essayer de supprimer quoi que ce soit:

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

Toutefois, si les files de fusion ne font pas partie du transfert, vous devez spécifier des règles globales d'exclusion (c.-à-d. Spécifiées sur la command line) ou vous devez conserver vos propres files de fusion par directory côté réception. Un exemple du premier est ceci (supposons que les files .rules distants s'excluent eux-mêmes):

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

Dans l'exemple ci-dessus, le file extra.rules peut affecter les deux côtés du transfert, mais (côté envoi), les règles sont subordonnées aux règles fusionnées à partir des files .rules car elles ont été spécifiées après la règle de fusion par directory.

Dans un dernier exemple, le côté distant exclut les files .rsync-filter du transfert, mais nous voulons utiliser nos propres files .rsync-filter pour contrôler ce qui est supprimé du côté réception. Pour ce faire, nous devons spécifiquement exclure les files de fusion par directory (afin qu'ils ne soient pas supprimés), puis mettre des règles dans les files locaux pour contrôler ce qui ne devrait pas être supprimé. Comme l'une de ces commands:

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

Si j'ai bien compris, le --exclude pourrait être ce que vous searchz:

 $ 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 

J'ai une réponse pour ça. Je pense que ça marche. Et ça marche pour moi. D'abord, vous devriez avoir à rsync des files distants aux files locaux. Ensuite, côté local contient tous les files.

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

maintenant dans le côté local

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

Ensuite, vous pouvez supprimer les files ou faire ce que vous voulez (côté local). Dans votre question, vous supprimez ces files.

files supprimés

 a.txt b.txt 

Après cela, vous pouvez rsync files locaux sur le côté distant.Puis les deux côtés ont les mêmes files.

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

il donne

 c.txt d.txt README.md 

files à distance et côté local (en utilisant --delete , il supprime les autres files du côté distant qui ne correspondent pas avec le côté local ).