Esiste un modo più veloce per rimuovere una directory di "rm -rf"?


32

Ho una cartella che ha molti file e "rm -rf" richiede molto tempo per essere completata. Esiste un modo più veloce per rimuovere una directory e il suo contenuto (sottodir, ecc.)?


Per chiunque sia interessato vedi: slashroot.in/comment/1286#comment-1286 trova briscole perl briscole rsync
Rinzwind

Risposte:


33

Si potrebbe provare a scollegare l'inode per la directory, ma che si sarebbe partire con un intero carico di file orfani che fsck si flip out circa.

rm è buono come si arriva.


Alcune persone citano casi limite in cui alcune cose sono più veloci di altre. Ma assicuriamoci di confrontare le migliori versioni delle stesse cose.

Se vuoi eliminare una directory e tutto ciò che contiene, ti sto suggerendo:

rm -rf path/to/directory

rmsarà internamente elencare i file e le directory che sta per cancellare. E questo è tutto in C compilato . Sono quei due motivi per cui è più veloce.

Questo non è decisamente la stessa cosa rm -rf path/to/directory/*che si espanderà a livello di shell e passerà un sacco di argomenti rm. Quindi rmdeve analizzare quelli e quindi ricorrere da ciascuno. È molto più lento.

Proprio come un "benchmark" che confronta find path/to/directory -exec {} \;è una sciocchezza. Che viene eseguito rmuna volta per file che trova. Così lenta. Trova può generare argomenti con comandi di costruzione in stile xargs -exec rm {} +ma è lento quanto l'espansione. Puoi chiamare -deleteche utilizza una unlinkchiamata interna al kernel (come rmfa) ma inizialmente funzionerà solo con i file.

Quindi ripetere, a meno che non si getti il ​​disco nel liquido caldo magma, rmè re .


In una nota correlata, diversi filesystem eliminano le cose a velocità diverse a causa del modo in cui sono strutturate. Se lo fai regolarmente, potresti voler archiviare questi file in una partizione formattata in XFS che tende a gestire le cancellazioni abbastanza velocemente.

O usa un disco più veloce. Se hai tonnellate di RAM, usare /dev/shm(un disco RAM) potrebbe essere un'idea.


Non puoi effettivamente utilizzare la unlinkchiamata di sistema nelle directory (otterrai un EISDIRerrore), quindi la prima opzione non è possibile.
James Henstridge,

Mv in / tmp sarebbe più veloce? Sembra che anche mv impieghi molto tempo.
Mohammad Moghimi,

@MohammadMoghimi: mving tra diversi filesystem / partizioni significa a cpseguito da a rm.
enzotib

3
@enzotib Tuttavia, se si /tmptrova sullo stesso filesystem, mi chiedo se mve il riavvio sarebbe più veloce? Non sono sicuro se /tmpsia stato eliminato usando rmcomunque.
Sparhawk,

1
rsyncin questo caso benchmark è più veloce di rm -rf: web.archive.org/web/20130929001850/http://linuxnote.net/…
schmijos

11

A volte, find $DIR_TO_DELETE -type f -deleteè più veloce di rm -rf.

Potresti anche voler provare mkdir /tmp/empty && rsync -r --delete /tmp/empty/ $DIR_TO_DELETE.

Infine, se è necessario eliminare il contenuto di una partizione intero, il più veloce sarà probabilmente umount, mkfse ri- mount.


1
non è type -fper indicare un file e non una directory? inoltre, l'aggiunta -printmostra i file mentre vengono eliminati.
leetbacoon,

8

Se non hai bisogno di spazio libero, il modo più rapido è ritardare la cancellazione e farlo in background:

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

Quindi disporre di un crontab che lo fa in background, in un momento di silenzio, con una bassa priorità I / O:

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

Gli appunti:

  • controlla il tuo output prima di rimuovere l'eco nel crontab!
  • la directory .delete_me deve trovarsi nello stesso filesystem - nel caso in cui non sia ovvio per tutti.

Aggiornamento: ho trovato un trucco per eseguire più rm in parallelo - questo aiuterà se si dispone di un array di dischi di grandi dimensioni:

ionice -c 3 nice find target_directory -depth -maxdepth 3 | xargs -d \n -P 5 -n 5 rm -rf
  • -profondità per eseguire un attraversamento in profondità.

  • -maxdepth per limitare la profondità dell'attraversamento della directory in modo da non finire ad ascoltare singoli file.

  • -d \ n per gestire gli spazi nei nomi dei file.

  • -P e -n gestisce il grado di parallelismo (controlla la manpage).

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

Aggiornamento 2 (2018): con ZFS fornito con Ubuntu 18.04 lo uso per tutto e creerò un nuovo set di dati di per qualsiasi grande progetto. Se pianifichi in anticipo e lo fai in anticipo, puoi semplicemente "zfs distruggere" un filesystem quando hai finito. ;-)

Ho usato le istruzioni dal wiki di zfsonlinux per installare Ubuntu su ZFS in modo nativo: https://github.com/zfsonlinux/zfs/wiki/Ubuntu-18.04-Root-on-ZFS


2
Invece di quell'ultimo comando, usa find target_dir -maxdepth 3 -depth -type d -print0 | xargs -0 -P 5 rm -rf. L' -depthopzione dice finddi elencare prima i bambini.
muru,

2

Penso che il problema sia che non esiste un modo perfetto per rimuovere una directory molto grande e il suo intero insieme di contenuti senza un vero sistema di archiviazione indicizzato che comprenda il non-linking e non significhi che pensi che abbia file mancanti in FSCK. Ci deve essere una fiducia.

Ad esempio ho zoneminder in esecuzione per un campo da golf. Ho costruito un raid su Linux di 1,5 TB per gestire l'immensa quantità di dati che acquisisce un giorno (12 feed di videocamera) su come ha funzionato su un'unità da 120 GB oltre me. Per farla breve, la cartella per tutti i dati acquisiti è di circa 1,4 TB della sua memoria. Molto da eliminare

Dover reinstallare ZM ed eliminare la vecchia libreria da 1,4 TB non è divertente perché possono essere necessari 1-2 giorni per eliminare le vecchie immagini.

Un vero FS indicizzato consente la caduta della directory e sa che i dati sottostanti sono morti e l'azzeramento dei dati è una perdita di tempo e risorse del nostro PC. Dovrebbe essere un'opzione per azzerare i dati eliminati. RM richiede molto tempo nel mondo reale su ext4.

Risposta: Scollegare ricorsivamente tutti i file sarebbe leggermente più veloce marginalmente ma dovresti comunque dedicare un tempo per eseguire FSCK.

Crea uno script che esegue un comando "FOR" ricorsivo in grado di "scollegare" tutti i file nelle cartelle, quindi semplicemente rm o rmdir tutte le cartelle per ripulirlo. Esegui manualmente FSCK per azzerare il resto dei dati quando è conveniente. Kinda Lazy non l'ha scritto scusa :).


0

Anche se non utile se si desidera eliminare una directory esistente, menzionerò che una possibile strategia se sai che avrai una directory con un lof di file che dovrai eliminare regolarmente è quella di mettere la directory sul suo stesso filesystem ( ad es . partizione). Quindi, quando è necessario eliminarlo, smontarlo, eseguire un mkfse rimontarlo. Ad esempio OpenBSD consiglia di farlo per/usr/obj , in cui molti file vengono creati durante una build del sistema e devono essere eliminati prima della build successiva.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.