Eliminar miles de millones de archivos de un directorio mientras ve el progreso también

36

Tengo un directorio de 30 TB con miles de millones de archivos que son formalmente todos archivos JPEG. Estoy borrando cada carpeta de archivos de esta manera:

sudo rm -rf bolands-mills-mhcptz

Este comando simplemente se ejecuta y no muestra nada si funciona o no.

Quiero ver cómo está eliminando archivos o cuál es el estado actual del comando.

Junaid Farooq
fuente
19
No respuestas: a veces es más rápido hacer una copia de seguridad de las cosas que desea conservar, formatear y restaurar las cosas que desea conservar. Otras respuestas: unix.stackexchange.com/questions/37329/…
Eric Towers
2
Si solo quiere una idea del progreso, en lugar de saber qué archivos en particular se han eliminado, puede ejecutar "df / dev / sd_whatever_the_drive_is".
jamesqf
11
¿Cómo terminaste con miles de millones de archivos en un solo directorio?
Lightness compite con Monica el
1
@MichaelHampton Pero si los archivos no son un conjunto de datos separado, puede llevar mucho tiempo. (en ZFS) serverfault.com/questions/801074/…
v7d8dpo4
55
Miles de millones de archivos, ¿eh? Tratar rm -ri. ¡Será divertido!
OldBunny2800

Respuestas:

98

Puede utilizar rm -vpara rmimprimir una línea por archivo eliminado. De esta manera, puede ver que rmefectivamente está trabajando para eliminar archivos. Pero si tiene miles de millones de archivos, todo lo que verá es que rmtodavía funciona. No tendrá idea de cuántos archivos ya se eliminaron y cuántos quedan.

La herramienta pvpuede ayudarlo con una estimación del progreso.

http://www.ivarch.com/programs/pv.shtml

Así es como invocaría rmcon pvsalida de ejemplo

$ rm -rv dirname | pv -l -s 1000 > logfile
562  0:00:07 [79,8 /s] [====================>                 ] 56% ETA 0:00:05

En este ejemplo artificial dije pvque hay 1000archivos. La salida de pvmuestra que 562 ya están eliminados, el tiempo transcurrido es de 7 segundos y la estimación para completar es de 5 segundos.

Alguna explicación:

  • pv -lhace pvcontar por nuevas líneas en lugar de bytes
  • pv -s numberle dice pvcuál es el total para que pueda darle una estimación.
  • La redirección al logfilefinal es para una salida limpia. De lo contrario, la línea de estado de pvse mezcla con la salida de rm -v. Bonificación: tendrá un archivo de registro de lo que se eliminó. Pero cuidado, el archivo se volverá enorme. También puede redirigir a /dev/nullsi no necesita un registro.

Para obtener el número de archivos puede usar este comando:

$ find dirname | wc -l

Esto también puede llevar mucho tiempo si hay miles de millones de archivos. También puede usar pvaquí para ver cuánto ha contado

$ find dirname | pv -l | wc -l
278k 0:00:04 [56,8k/s] [     <=>                                              ]
278044

Aquí dice que tardó 4 segundos en contar 278k archivos. El recuento exacto al final ( 278044) es la salida de wc -l.

Si no desea esperar el recuento, puede adivinar el número de archivos o usarlo pvsin estimación:

$ rm -rv dirname | pv -l > logfile

De esta manera, no tendrá una estimación para terminar, pero al menos verá cuántos archivos ya están eliminados. Redireccionar a /dev/nullsi no necesita el archivo de registro.


Nitpick:

  • lo que realmente necesita sudo?
  • generalmente rm -res suficiente para eliminar de forma recursiva. No hay necesidad de rm -f.
lesmana
fuente
55
Buen uso de pv, suponiendo que no sea demasiado costoso contar los miles de millones de archivos ;-). (¡Podría tomar casi tanto tiempo como rmse supone que debe medir!)
Stephen Kitt
77
@StephenKitt Esto es lo que realmente me molesta (y a muchas otras personas) acerca de la utilidad de archivos de Windows: siempre , sin falta, cuenta el número y el tamaño de los archivos antes de eliminarlos, a menos que la unidad sea mucho más lenta que el procesador, toma casi lo mismo siempre y cuando la eliminación real!
wizzwizz4
@ wizzwizz4 De hecho! Sin embargo, hay más que eso en el IIRC: comprueba que puede eliminar todo antes de eliminar cualquier cosa , para aumentar las posibilidades de que las eliminaciones sean "todo o nada". Hace muchos años escribí un controlador de sistema de archivos para Windows, hubo algunas rarezas con las que tuvimos que lidiar, incluidas algunas relacionadas con la forma en que Explorer elimina, pero no puedo recordar los detalles. (¡Recuerdo que crear una carpeta implica escribir y eliminar un archivo en la nueva carpeta!)
Stephen Kitt
77
@StephenKitt Tal vez estoy equivocado, pero ¿no es el cuello de botella, además del acceso al disco, la salida del terminal? Creo que pvactualiza la barra de progreso solo una vez por segundo, a pesar de su entrada. Por lo tanto, el terminal solo necesita mostrar una línea en lugar de una tonelada cada segundo. pvsolo necesita incrementar un contador por cada nueva línea que encuentre; eso tiene que ser más rápido que hacer un ajuste de línea, y más para mostrar una línea en una terminal. Creo que correr de pvesta manera hace que la eliminación de archivos sea más rápida que simplemente rm -rv.
JoL
1
@skywinderrm -rv dirname | pv -l -s $(find dirname | wc -l) > logfile
lesmana
28

Mira la respuesta de lesmana , es mucho mejor que la mía, especialmente el último pvejemplo, que no tomará mucho más tiempo que el silencio original rmsi lo especificas en /dev/nulllugar de logfile.

Suponiendo que su rmsoporte admite la opción (probablemente lo haga ya que está ejecutando Linux), puede ejecutarlo en modo detallado con -v:

sudo rm -rfv bolands-mills-mhcptz

Como se ha señalado por varios comentaristas, esto podría ser muy lento debido a la cantidad de salida que genera y muestra el terminal. En su lugar, podría redirigir la salida a un archivo:

sudo rm -rfv bolands-mills-mhcptz > rm-trace.txt

y mira el tamaño de rm-trace.txt.

Stephen Kitt
fuente
55
En realidad, esto puede ralentizar el borrado abajo a causa de toda la salida que se genera y se rindió a un terminal :)
rackandboneman
2
Por supuesto que se ralentizará. Escribir miles de millones de líneas en un archivo no ocurre en tiempo cero.
user207421
23

Otra opción es ver disminuir la cantidad de archivos en el sistema de archivos. En otra terminal, ejecute:

watch  df -ih   pathname

El recuento de inodos usados ​​disminuirá a medida rmque avance. (A menos que los archivos tengan en su mayoría múltiples enlaces, por ejemplo, si el árbol se creó con cp -al). Esto rastrea el progreso de eliminación en términos de número de archivos (y directorios). dfsin -irastreará en términos de espacio utilizado.

También puede ejecutar iostat -x 4para ver operaciones de E / S por segundo (así como kiB / s, pero eso no es muy relevante para E / S de metadatos puros).


Si tiene curiosidad sobre en qué archivos rmestá trabajando actualmente, puede adjuntarle un archivo stracey observar cómo las unlink()llamadas del sistema (y las respuestas) se escuchan en su terminal. por ej sudo strace -p $(pidof rm). Puedes ^cseparar el strace rmsin interrumpirlo.

Olvidé si rm -rcambia el directorio en el árbol que está eliminando; si es así, podrías mirar /proc/<PID>/cwd. A /proc/<PID>/fdmenudo puede tener un directorio fd abierto, por lo que puede ver eso para ver qué rmestá viendo actualmente su proceso.

Peter Cordes
fuente
2
df -ihes de hecho una buena forma barata de ver el rmprogreso.
Stephen Kitt
Por cierto, esto no funciona en BTRFS, donde el recuento de inodo utilizado siempre es cero. :( Lo mismo para FAT32, pero probablemente no tenga miles de millones de archivos en su /bootpartición del sistema EFI.
Peter Cordes
4

Si bien lo anterior responde a todo uso rm, en rmrealidad puede ser bastante lento para eliminar una gran cantidad de archivos, como recientemente observé cuando extraer ~ 100K archivos de un archivo .tar en realidad tomó menos tiempo que eliminarlos. Aunque esto en realidad no responde la pregunta que hizo, una mejor solución a su problema podría ser utilizar un método diferente para eliminar sus archivos, como una de las respuestas a esta pregunta .

Mi método favorito personal es usar rsync -a --delete. Me parece que este método funciona lo suficientemente rápido como para que valga la facilidad de uso sobre la respuesta más votada a esa pregunta , en la que el autor ha escrito un programa en C que necesitaría compilar. (Tenga en cuenta que esto generará todos los archivos que se procesan en stdout, de manera similar rm -rv; esto puede ralentizar el proceso en una cantidad sorprendente. Si no desea esta salida, use rsync -aq --deleteo redirija la salida a un archivo).

El autor de esa respuesta dice:

El programa ahora (en mi sistema) eliminará 1000000 archivos en 43 segundos. El programa más cercano a esto fue rsync -a --delete, que tardó 60 segundos (que también elimina en orden, pero no realiza una búsqueda de directorio eficiente).

He descubierto que esto es lo suficientemente bueno para mis propósitos. También es potencialmente importante a partir de esa respuesta, al menos si está usando ext4:

Como previsión, uno debe eliminar el directorio afectado y rehacerlo después. Los directorios solo aumentan de tamaño y pueden seguir teniendo un bajo rendimiento, incluso con algunos archivos dentro debido al tamaño del directorio.

Hitechcomputergeek
fuente
eh, hubiera esperado rmy / o find --deleteser eficiente. Punto interesante sobre la eliminación en orden de clasificación para evitar reequilibrios de b-tree durante la eliminación. No estoy seguro de cuánto se aplica a otros sistemas de archivos. XFS tampoco es excelente con millones de archivos por directorio. IDK sobre BTRFS, pero tengo la impresión de que podría ser bueno para ese tipo de cosas.
Peter Cordes
¿
Esa
@Menasheh Buen punto, lo edité en mi respuesta.
Hitechcomputergeek
3

Una cosa que podría hacer sería iniciar el rmproceso en segundo plano (sin salida, por lo que no se ralentizará) y luego monitorearlo en primer plano con un simple comando (a) :

pax> ( D=/path/to/dir ; rm -rf $D & while true ; do
...>   if [[ -d $D ]] ; then
...>     echo "$(find $D | wc -l) items left"
...>   else
...>     echo "No items left"
...>     break
...>   fi
...>   sleep 5
...> done )

27912 items left
224 items left
No items left

pax> _

El find/wccombo podría reemplazarse con cualquier herramienta capaz de darle las unidades que desea.


(a) Bueno, relativamente simple, en comparación con, digamos, la física nuclear, la hipótesis de Riemann o qué comprarle a mi esposa para Navidad :-)


fuente
0

Hace un tiempo escribí algo para imprimir la tasa de impresión de las líneas. Puede ejecutar rm -rfv | ./countere imprimirá líneas por segundo / min. Aunque no es un progreso directo, le dará algunos comentarios sobre la tasa de progreso, ¿tal vez rmse haya metido en un sistema de archivos de red o similar?

El enlace al código está aquí:

http://www.usenix.org.uk/code/counter-0.01.tar.gz

Ed Neville
fuente