RSYNC ne supprime pas les répertoires source

27

J'utilise rsync pour récupérer des fichiers essentiels sur un serveur, puis supprimer les fichiers du serveur une fois que je les ai localement. La commande complète que j'exécute est ci-dessous.

Cela supprime correctement les fichiers sur le serveur source, mais des répertoires vides restent toujours. Je ne reçois aucun message ni erreur. Toute sortie est normale. C'est peut-être la fonctionnalité prévue.

Comment puis-je dire à rsync de tout nettoyer, y compris les répertoires?

rsync --progress -vrzh --remove-source-files

La version est 3.0.9 aux deux extrémités.

Sajan Parikh
la source
Connexes: unix.stackexchange.com/questions/78375/… | serverfault.com/questions/384110/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Réponses:

13

Le comportement --remove-source-filesque vous observez est exactement celui spécifié par man rsync:

--remove-source-files

   This tells rsync to remove from the sending side the files (meaning non-directories) that are a part of the transfer and have been successfully duplicated on the receiving side.

Il n'y a pas de commande spécifique pour supprimer les répertoires, comme le montrent clairement ces deux discussions dans StackExchange et ServerFault . La solution suggérée consiste à émettre deux commandes distinctes:

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

Le dernier morceau de la commande suggéré dans ces deux messages,

 rmdir source/

qui est nécessaire pour supprimer le répertoire source (maintenant vidé) a ce formulaire dans ces messages parce que les OP et les réponses utilisent rsync pour déplacer de grandes quantités de fichiers sur la même machine. Dans votre cas, vous devrez le faire manuellement.

MariusMatutiae
la source
5
La rsync --deletesuggestion est dangereuse, car elle ignore la possibilité que la rsync ne soit pas terminée ou qu'il y ait de nouveaux fichiers à la source. La findméthode de @ slhck ci-dessous est beaucoup plus sûre.
Sai
29

La page de manuel dit même:

--remove-source-files   sender removes synchronized files (non-dirs)

Si vous souhaitez supprimer des répertoires vides de votre source, s'il reste des fichiers, procédez comme suit:

find . -depth -type d -empty -delete

Mais pour un répertoire racine vide, une rm -rf <directory>volonté suffit bien sûr.

slhck
la source
5
oui, c'est la seule solution. c'est une sorte de fonctionnalité absente stupide de rsync ... rsync sait quand il a traité le dernier fichier dans un répertoire ... il est assez facile de supprimer le répertoire aussi s'il est vide.
Erik Aronesty
4
Attention, l'émission de "rm -rf" est sujette aux conditions de course et je la décourage.
Raúl Salinas-Monteagudo
Variante qui n'efface pas le répertoire vide de niveau supérieur:find some_dir -depth -type d -empty -not -path some_dir -delete
Cameron Tacklind
5

L'utilisation de " rm -rf " a une condition de concurrence inhérente, vous pouvez notamment supprimer les fichiers qui viennent d'être créés entre les appels rsync et rm .

Je préfère utiliser:

rsync --remove-source-files -a server: entrant / entrant / &&

serveur ssh trouver entrant -type d -delete

Cela ne supprimera PAS les répertoires s'ils ne sont pas vides.

Raúl Salinas-Monteagudo
la source
2
Le rm -rfva également supprimer des fichiers qui ne sont pas transférés pour une raison quelconque.
Kristian
1
Cette réponse manque l' -depthoption qui demande findde traiter dans le bon ordre. À la suite de cette erreur, les répertoires qui ne contiennent que des répertoires vides (éventuellement récursivement) ne seront pas supprimés. La variante de @slhck a raison.
Stéphane Gourichon
1

-m, --prune-empty-dirs élaguer les chaînes de répertoires vides de la liste de fichiers

--force forcer la suppression des répertoires même s'ils ne sont pas vides

MarcoP
la source
1
Cela empêche simplement rsync de copier des répertoires vides. Il ne supprime pas les répertoires vides.
Navin
1

Supprimez les fichiers source, puis supprimez les répertoires pour être sûr.

# given this scenario where you generate folders 2014-01-01 etc.. that have an archive myfile.tar.gz
pushd $(mktemp -d)
mkdir 201{4..6}-{01..12}-{01..31}
for i in $(ls); do; touch $i/myfile.tar.gz;done;
# find and rsync on 10 CPU threads directories that match ./2015-*
find /tmp/tmp.yjDyF1jN70/src -type d -name '2015-*' | \
parallel \
--jobs 10 \
--progress \
--eta \
--round-robin \
rsync \
--hard-links \
--archive --verbose --protect-args \
--remove-source-files \
{} /tmp/tmp.yjDyF1jN70/dest
# now safely remove empty directories only
for i in $(ls /tmp/tmp.yjDyF1jN70/src); do; rmdir /tmp/tmp.yjDyF1jN70/src/$i; done;

Plus sur GNU Parallel

Daniel Andrei Mincă
la source