¿Hay alguna forma más rápida de eliminar un directorio que "rm -rf"?

32

Tengo una carpeta que tiene muchos archivos y "rm -rf" tarda mucho tiempo en completarse. ¿Hay alguna forma más rápida de eliminar un directorio y sus contenidos (subdirecciones, etc.)?

Mohammad Moghimi
fuente
Para cualquier persona interesada, consulte: slashroot.in/comment/1286#comment-1286 find trumps perl trumps rsync
Rinzwind

Respuestas:

33

Podrías intentar desvincular el inodo para el directorio, pero eso te dejaría con una carga completa de archivos huérfanos que fsck se volcarán.

rm es tan bueno como se pone.


Algunas personas mencionan casos extremos en los que algunas cosas son más rápidas que otras. Pero asegurémonos de que estamos comparando las mejores versiones de las mismas cosas.

Si desea eliminar un directorio y todo lo que contiene, le sugiero:

rm -rf path/to/directory

rmse internamente una lista de los archivos y directorios que va a eliminar. Y eso es todo en C compilado . Son esas dos razones por las que es más rápido.

Esto no es lo mismo rm -rf path/to/directory/*que expandirse a nivel de shell y pasar una gran cantidad de argumentos rm. Luego rmtiene que analizarlos y luego recurrir a cada uno. Eso es mucho más lento.

Así como un "punto de referencia" que se compara no find path/to/directory -exec {} \;tiene sentido. Eso se ejecuta rmuna vez por archivo que encuentra. Muy lento. Buscar argumentos de comandos de construcción al estilo xargs puede con -exec rm {} +pero eso es tan lento como la expansión. Puede llamar con -deleteuna unlinkllamada interna al núcleo (como lo rmhace), pero eso solo funcionará para los archivos al principio.

Entonces, para repetir, a menos que arrojes el disco al magma caliente líquido, rmes el rey .


En una nota relacionada, diferentes sistemas de archivos eliminan cosas a diferentes velocidades debido a cómo están estructurados. Si está haciendo esto de forma regular, es posible que desee almacenar estos archivos en una partición formateada en XFS que tiende a manejar las eliminaciones bastante rápido.

O use un disco más rápido. Si tiene toneladas de RAM, /dev/shmpodría ser una idea usar (un disco RAM).

Oli
fuente
En realidad, no puede usar la unlinkllamada del sistema en los directorios (obtendrá un EISDIRerror), por lo que esa primera opción no es posible.
James Henstridge
¿Sería mv to / tmp más rápido? Parece que mv también toma mucho tiempo.
Mohammad Moghimi
@MohammadMoghimi: mventre diferentes sistemas de archivos / particiones significa a cpseguido de a rm.
enzotib
3
@enzotib Sin embargo, si /tmpestá en el mismo sistema de archivos, me pregunto si mvy reiniciar sería más rápido. No estoy seguro si /tmpse borra usando de rmtodos modos.
Sparhawk
1
rsyncen este caso de referencia es más rápido que rm -rf: web.archive.org/web/20130929001850/http://linuxnote.net/…
schmijos
11

A veces, find $DIR_TO_DELETE -type f -deletees más rápido que rm -rf.

También es posible que desee probar mkdir /tmp/empty && rsync -r --delete /tmp/empty/ $DIR_TO_DELETE.

Finalmente, si necesita eliminar el contenido de una partición completa, lo más rápido probablemente sea umount, mkfsy re mount.

mivk
fuente
1
no es type -fdenotar un archivo y no un directorio? Además, agregar -printmuestra los archivos a medida que se eliminan.
Leetbacoon
8

Si no necesita el espacio libre, la forma más rápida es retrasar la eliminación y hacerlo en segundo plano:

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

Luego tenga un crontab que lo haga en segundo plano, en un momento tranquilo, con una baja prioridad de E / S:

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

Notas:

  • ¡verifique su salida antes de eliminar el eco en el crontab!
  • el directorio .delete_me debe estar en el mismo sistema de archivos, en caso de que no sea obvio para todos.

Actualización: Encontré un buen truco para ejecutar múltiples rm en paralelo; esto ayudará si tienes una gran matriz de discos:

ionice -c 3 nice find target_directory -depth -maxdepth 3 | xargs -d \n -P 5 -n 5 rm -rf
  • -profundidad para hacer un recorrido en profundidad primero.

  • -maxdepth para limitar la profundidad del recorrido del directorio para que no terminemos de escuchar archivos individuales.

  • -d \ n para manejar espacios en los nombres de archivo.

  • -P y -n maneja el grado de paralelismo (ver página de manual).

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

Actualización 2 (2018): con ZFS incluido con Ubuntu 18.04, lo uso para todo y crearé un nuevo conjunto de datos para cualquier gran proyecto. Si planifica con anticipación y hace esto de antemano, simplemente puede "zfs destruir" un sistema de archivos cuando haya terminado. ;-)

Utilicé las instrucciones del wiki de zfsonlinux para instalar Ubuntu en ZFS de forma nativa: https://github.com/zfsonlinux/zfs/wiki/Ubuntu-18.04-Root-on-ZFS

Lester Cheung
fuente
2
En lugar de ese último comando, use find target_dir -maxdepth 3 -depth -type d -print0 | xargs -0 -P 5 rm -rf. La -depthopción le indica finda la lista de niños primero.
Muru
2

Creo que el problema es que no hay una manera perfecta de eliminar un directorio muy grande y todo su conjunto de contenidos sin un verdadero sistema de archivo indexado que comprenda la desvinculación y no significa que piense que le faltan archivos al FSCK. Tiene que haber una confianza.

Por ejemplo, tengo zoneminder corriendo para un campo de golf. Construí una incursión en Linux de 1.5 TB para manejar la inmensa cantidad de datos que captura al día (12 alimentaciones de cámara). En resumen, la carpeta para todos los datos capturados es de aproximadamente 1,4 TB de su almacenamiento. Mucho para purgar

Tener que reinstalar ZM y purgar la biblioteca antigua de 1.4 TB no es divertido porque puede tomar de 1 a 2 días eliminar las imágenes antiguas.

Un verdadero FS indexado permite la caída del directorio y sabe que los datos que contiene están muertos y la eliminación de los datos a cero es una pérdida de tiempo y de recursos de la PC. Debería ser una opción para poner a cero los datos eliminados. RM lleva mucho tiempo en el mundo real en ext4.

Respuesta: Desvincular recursivamente todos los archivos sería marginalmente más rápido, pero aún tendría que reservar un tiempo para ejecutar FSCK.

Cree un script que ejecute un comando "FOR" recursivo que pueda "desvincular" todos los archivos de sus carpetas y luego simplemente rm o rmdir todas las carpetas para limpiarlo. Ejecute FSCK manualmente para poner a cero el resto de los datos cuando sea conveniente. Un poco vago no lo escribió, lo siento :).

Adam Lazo
fuente
0

Aunque no es útil si desea purgar un directorio existente, mencionaré que una posible estrategia si sabe que tendrá un directorio con una gran cantidad de archivos que deberá purgar regularmente es colocar el directorio en su propio sistema de archivos ( por ejemplo , partición). Luego, cuando necesite purgarlo, desmóntelo, ejecute a mkfsy vuelva a montarlo. Por ejemplo, OpenBSD aconseja hacer esto para/usr/obj , donde se crean muchos archivos durante una compilación del sistema, y ​​deben eliminarse antes de la próxima compilación.

fkraiem
fuente