Existe-t-il un moyen plus rapide de supprimer un répertoire que «rm -rf»?

32

J'ai un dossier qui contient de nombreux fichiers et "rm -rf" prend beaucoup de temps à compléter. Existe-t-il un moyen plus rapide de supprimer un répertoire et son contenu (sous-répertoires, etc.)?

Mohammad Moghimi
la source
Pour toute personne intéressée, voir: slashroot.in/comment/1286#comment-1286 find trumps perl
trumps

Réponses:

33

Vous pouvez essayer de dissocier l'inode du répertoire, mais cela vous laisserait toute une charge de fichiers orphelins qui fsck se retourneront.

rm est aussi bon que possible.


Quelques personnes mentionnent des cas marginaux où certaines choses sont plus rapides que d'autres. Mais assurons-nous de comparer les meilleures versions des mêmes choses.

Si vous souhaitez supprimer un répertoire et tout ce qu'il contient, je vous suggère:

rm -rf path/to/directory

rmlistera en interne les fichiers et répertoires qu'il va supprimer. Et c'est tout en C compilé . Ce sont ces deux raisons pour lesquelles c'est le plus rapide.

Ce n'est vraiment pas la même chose que celle rm -rf path/to/directory/*qui se développera au niveau du shell et passera une charge d'arguments dans rm. Il rmfaut ensuite les analyser, puis récuser de chacun. C'est beaucoup plus lent.

Tout comme une «référence» qui compare find path/to/directory -exec {} \;est un non-sens. Cela s'exécute rmune fois par fichier qu'il trouve. Tellement lent. Les arguments de commandes de construction de style can xargs peuvent être trouvés, -exec rm {} +mais c'est aussi lent que l'expansion. Vous pouvez appeler -deletequi utilise un unlinkappel interne au noyau (comme le rmfait), mais cela ne fonctionnera que pour les fichiers au début.

Donc, répéter, à moins que vous ne jetiez le disque dans du magma chaud liquide, rmest roi .


Sur une note connexe, différents systèmes de fichiers suppriment des éléments à des taux différents en raison de leur structure. Si vous faites cela régulièrement, vous voudrez peut-être stocker ces fichiers dans une partition formatée en XFS qui a tendance à gérer les suppressions assez rapidement.

Ou utilisez un disque plus rapide. Si vous avez des tonnes de RAM, utiliser /dev/shm(un disque RAM) pourrait être une idée.

Oli
la source
Vous ne pouvez pas réellement utiliser l' unlinkappel système sur les répertoires (vous obtiendrez une EISDIRerreur), de sorte que la première option n'est pas possible.
James Henstridge
Est-ce que mv to / tmp serait plus rapide? Il semble que mv prenne aussi beaucoup de temps.
Mohammad Moghimi
@MohammadMoghimi: mving entre différents systèmes de fichiers / partitions signifie un cpsuivi d'un rm.
enzotib
3
@enzotib Cependant, si /tmpest sur le même système de fichiers, je me demande si mvet redémarrer serait plus rapide? Je ne sais pas si /tmpest effacé en utilisant de rmtoute façon.
Sparhawk
1
rsyncdans ce cas de référence est plus rapide que rm -rf: web.archive.org/web/20130929001850/http://linuxnote.net/…
schmijos
11

Parfois, find $DIR_TO_DELETE -type f -deletec'est plus rapide que rm -rf.

Vous pouvez également essayer mkdir /tmp/empty && rsync -r --delete /tmp/empty/ $DIR_TO_DELETE.

Enfin, si vous avez besoin de supprimer le contenu d'une partition entière, le plus rapide sera probablement umount, mkfset re mount.

mivk
la source
1
n'est pas type -fde désigner un fichier et non un répertoire? l'ajout -printmontre également les fichiers au fur et à mesure qu'ils sont supprimés.
leetbacoon
8

Si vous n'avez pas besoin de l'espace libre, le moyen le plus rapide est de retarder la suppression et de le faire en arrière-plan:

  • mkdir .delete_me
  • mv big-directory-that-i-want-gone .delete_me

Ensuite, ayez un crontab qui le fait en arrière-plan, à un moment calme, avec une faible priorité d'E / S:

3 3 * * * root ionice -c 3 nice find /path/to/.delete_me -maxdepth 1 ! -name \. -exec echo rm -rf "{}" +

Remarques:

  • vérifiez votre sortie avant de supprimer l'écho dans la crontab!
  • le répertoire .delete_me doit être dans le même système de fichiers - au cas où ce ne serait pas évident pour tout le monde.

Mise à jour: j'ai trouvé une astuce intéressante pour exécuter plusieurs rm en parallèle - cela vous aidera si vous avez une grande baie de disques:

ionice -c 3 nice find target_directory -depth -maxdepth 3 | xargs -d \n -P 5 -n 5 rm -rf
  • -depth pour effectuer une traversée en profondeur d'abord.

  • -maxdepth pour limiter la profondeur de la traversée du répertoire afin de ne pas finir par écouter des fichiers individuels.

  • -d \ n pour gérer les espaces dans les noms de fichiers.

  • -P et -n gère le degré de parallélisme (consultez la page de manuel).

réf: http://blog.liw.fi/posts/rm-is-too-slow/#comment-3e028c69183a348ee748d904a7474019

Mise à jour 2 (2018): avec ZFS livré avec Ubuntu 18.04, je l'utilise pour tout et je vais créer un nouvel ensemble de données pour tout grand projet. Si vous planifiez à l'avance et que vous le faites à l'avance, vous pouvez simplement "zfs détruire" un système de fichiers lorsque vous avez terminé. ;-)

J'ai utilisé les instructions du wiki zfsonlinux pour installer Ubuntu sur ZFS nativement: https://github.com/zfsonlinux/zfs/wiki/Ubuntu-18.04-Root-on-ZFS

Lester Cheung
la source
2
Au lieu de cette dernière commande, utilisez find target_dir -maxdepth 3 -depth -type d -print0 | xargs -0 -P 5 rm -rf. L' -depthoption indique findde répertorier les enfants en premier.
muru
2

Je pense que le problème est qu'il n'y a pas de moyen parfait de supprimer un très grand répertoire et tout son ensemble de contenus sans un véritable système de classement indexé qui comprend la dissociation et ne signifie pas qu'il pense qu'il manque des fichiers ala FSCK. Il doit y avoir une confiance.

Par exemple, j'ai zoneminder qui court pour un terrain de golf. J'ai construit un raid Linux de 1,5 To pour gérer l'immense quantité de données qu'elle capture par jour (12 flux de caméra). La façon dont elle fonctionnait sur un lecteur de 120 Go me dépasse. Pour faire court, le dossier de toutes les données capturées représente environ 1,4 To de son stockage. Beaucoup à purger

Il n'est pas amusant de réinstaller ZM et de purger l'ancienne bibliothèque de 1,4 To car cela peut prendre 1 à 2 jours pour supprimer les anciennes images.

Un véritable FS indexé permet la suppression du répertoire et sait que les données qu'il contient sont mortes et que la mise à zéro des données est une perte de temps et de ressources PC. Cela devrait être une option pour mettre à zéro les données supprimées. RM prend juste trop de temps dans le monde réel sur ext4.

Réponse: la dissociation récursive de tous les fichiers serait légèrement plus rapide, mais vous devrez toujours réserver un temps pour exécuter FSCK.

Créez un script exécutant une commande récursive "FOR" qui peut "dissocier" tous les fichiers sous vos dossiers, puis juste rm ou rmdir tous les dossiers pour le nettoyer. Exécutez manuellement FSCK pour mettre à zéro le reste des données lorsque cela vous convient. Un peu paresseux ne l'a pas écrit désolé :).

Adam Lazo
la source
0

Bien que cela ne soit pas utile si vous souhaitez purger un répertoire existant, je mentionnerai qu'une stratégie possible si vous savez que vous aurez un répertoire avec une lof de fichiers que vous devrez purger régulièrement consiste à placer le répertoire sur son propre système de fichiers ( par exemple , partition). Ensuite, lorsque vous devez le purger, le démonter, exécuter un mkfset le remonter. Par exemple, OpenBSD conseille de le faire pour/usr/obj , où de nombreux fichiers sont créés lors d'une build du système, et doivent être supprimés avant la build suivante.

fkraiem
la source