Déplacer des fichiers et supprimer des répertoires avec rsync?

17

Récemment, j'ai dû supprimer un grand nombre de fichiers (plus d'un million) et j'ai lu cela en faisant:

rsync -av --delete `mktemp -d`/ ~/source && rmdir ~/source

C'était l'un des moyens les plus optimisés de le faire, et je peux garantir que c'est plus rapide que rm -rf.

Je ne suis pas un expert en la matière, mais d'après ma compréhension, la raison des performances de rsync a quelque chose à voir avec la façon dont il répertorie les fichiers (LIFO au lieu de FIFO, je suppose). Maintenant, le problème est que je dois également déplacer un grand nombre de fichiers de manière efficace. Après avoir cherché un peu, j'ai trouvé ceci:

rsync -av --ignore-existing --remove-source-files ~/source ~/destination

Bien que cela supprime tous les déplacés de fichiers dans ~/sourceles répertoires restent là. Comme j'ai une structure de répertoires de type "round-robin", le nombre de files/directoriesest très proche de 1, donc je suis obligé d'exécuter à nouveau la première commande pour se débarrasser entièrement du répertoire:

rsync -av --ignore-existing --remove-source-files ~/source ~/destination && \
rsync -av --delete `mktemp -d`/ ~/source && rmdir ~/source

Une ligne droite mvse terminerait presque instantanément, mais mon ~/destinationrépertoire contient des fichiers qui devraient être conservés, ce mvn'est donc pas une option. J'ai trouvé les options --prune-empty-dirset --forcersync, mais aucune ne semble fonctionner comme je m'y attendais:

--force                 force deletion of directories even if not empty
--prune-empty-dirs      prune empty directory chains from the file-list
--remove-source-files   sender removes synchronized files (non-dirs)

Existe-t-il un moyen d'imiter un mouvement avec rsync en une seule fois?

Alix Axel
la source
2
Si vous n'obtenez pas de réponse ici, essayez de publier sur la liste rsync. Ils sont très utiles. lists.samba.org/mailman/listinfo/rsync
Joe
connexes: superuser.com/questions/676671/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Réponses:

7

J'ai trouvé ce fil sur stackoverflow intitulé: Suppression de dossiers avec rsync "move"? , qui pose essentiellement la même question. L'une des réponses a suggéré de faire les rsynccommandes in 2 car il semble qu'il n'y ait pas une seule commande qui puisse effectuer le déplacement / suppression des fichiers et des répertoires source.

$ rsync -av --ignore-existing --remove-source-files source/ destination/ && \
  rsync -av --delete `mktemp -d`/ source/ && rmdir source/

Alternativement, vous pouvez le faire en utilisant cette commande:

$ rsync -axvvES --remove-source-files source_directory /destination/ && \
  rm -rf source_directory

Pas idéal mais fait le boulot.

slm
la source
Oui, c'est moi qui ai répondu à cette question (et la même "solution" est aussi sur cette question). = P
Alix Axel
@AlixAxel - Ha, désolé, je n'ai même pas remarqué que vous avez répondu à celle-là. Tant pis. Dois-je supprimer cette réponse alors?
slm
3
L'utilisation rsyncde l'élagage des répertoires ne se sent pas bien et il y a toujours un danger avec rm -rf. Je recommanderais que la 2ème étape soit:find source/ -d -type d -exec rmdir {} \;
loufoque
2
Je me sens juste obligé d'ajouter, de ne jamais utiliser -deleteet --remove-source-filesdans une seule commande rsync (les exemples ci-dessus sont très bien, c'est tangentiel). Si vous interrompez puis réexécutez ce que je décris, vous perdrez les fichiers transférés. Ce que j'ai fait auparavant :(
Sridhar Sarnobat
Lors du nettoyage avec find, je préfère ceci: find source/ -type d -empty -delete cela me donne une étrange assurance que cela ne fera pas que tout encombrer.
greyfade
10

Du commentaire loufoque à la réponse de slm ( Déplacer des fichiers et supprimer des répertoires avec rsync? ) Je recommanderais ces 2 commandes comme réponse:

rsync -av --ignore-existing --remove-source-files source/ destination/ && \
find source/ -depth -type d  -empty -exec rmdir "{}" \;

L'avantage est, comme l'a dit Zany, qu'il y a toujours un danger à utiliser rm -rf si vous ne le faites pas bien ou pour les débutants.

J'ai ajouté 2 options, -depth et -empty et même si je ne sais pas si c'est vraiment nécessaire, cela rend la 2e commande plus portable pour d'autres situations et encore plus sûre (elle fait toujours la bonne chose si certains répertoires ne sont pas vides et commence à supprimer du point le plus profond d'une arborescence de répertoires)

mit
la source
pourquoi pas juste -deleteau lieu de -exec rmdir {} \;?
moutons volants
@flying_sheep voir le commentaire de user7000 dans la réponse de sim: quand rsync ist interrompu , vous pouvez perdre des fichiers
mit
Lorsque rsync est interrompu, la recherche ne démarre jamais ou non? Ainsi, la suppression dans un deuxième rsync ne devrait pas être un problème. Mais -delete supprime également les fichiers, à la place rmdir ne supprime jamais les fichiers, seulement les répertoires. Les deux (-delete et rmdir) vérifient les répertoires s'ils sont vides avant de les supprimer.
benba
De plus, les pages de manuel indiquent que vous devriez utiliser -execdir au lieu de -exec ...
benba
2

Cela fait le travail en une seule étape. Notez la fin / barre oblique / sur les chemins source et cible.

rsync \
    -ruval \
    --ignore-existing \
    --remove-source-files \
    --prune-empty-dirs \ 
    /source/path/ /target/path/

Je fais écho à la mise en garde de user7000 de ne pas utiliser --deleteet --remove-source-filesensemble dans le même appel à rsync. Si l'opération échoue ou est interrompue et que le même appel est répété, vous perdrez des données. En cas de doute, utilisez l' --dry-runoption pour voir ce qui serait fait.

gjvc
la source
-ruvalsemble redondant. -aest équivalent à -rlptgoD, qui comprend à la fois -ret -l.
Greyfade