Apartamento En Familia

Apartamento En Familia
Apartamento de playa para vacaciones. http://www.apartamentoenfamilia.es. Número registro HUTT-005768

martes, 11 de diciembre de 2012

Solucionar el problema "/bin/rm: Argument list too long"

rm es un comando de la familia de sistemas operativos Unix usada para eliminar archivos y directorios del sistema de archivos1 . Esta orden debe utilizarse con cautela, ya que puede ser muy destructiva, debido a que, al momento de ser llamada, por omisión borra los archivos sin pedir confirmación.
Proviene de la palabra remove que significa "borrar" en inglés.

(Fuente Wikipedia)

En algunas ocasiones me ha ocurrido que mirando de borrar los archivos de una carpeta de manera masiva (rm *), he obtenido el error

bash: /bin/rm: Argument list too long

Bien, el problema es bastante claro, ya que nos dice que la cantidad de archivos a borrar es muy grande y no puede gestionarla. La verdad es que uno piensa que un comando como rm tiene que estar preparado para eso y más, pero al final, como todo tiene sus pros y sus contras, la cuestión es encontrar la solución a esa limitación.

¿Que causa el problema?

El problema es una limitación en el buffer de la función exec(), el cual es de 128K. Esta función es usada por muchas otras funciones y por tanto afecta a muchas operaciones. Por regla general, este problema no afecta al dia a dia ni al usuario doméstico, si bien en administración de servidores nos podemos ir encontrando de vez en cuando. Existe una explicación bastante precisa en la wiki de Debian: ArgumentListTooLong
Una traducción aproximada seria esta:

El limite afecta la funcion execve() del kernel, la cual es usada por todas las demás funciones exec() (execl, execlp, execle,etc). La funcion trabaja creando un buffer de 128k al final del espacio de memoria y copiando el comando y el entorno para el nuevo proceso en este espacio. En ese momento el kernel carga el nuevo programa en memoria, configura sus punteros argv y endv, y salta al punto de entrada del programa. El mensaje de error "argument list too long" es causado por el codigo de error !E2BIG, siendo devuelto por la funcion execve(), cuando es incapaz de introducir el argumento y entorno suministrados dentro del buffer de 128k.
(Traducción |_ocutus)


¿Como podemos arreglarlo?

Más que arreglar el problema, deberíamos hablar de como evitarlo. Para evitar que nos salga este error, lo que podemos hacer es borrar de otra manera que no sea mediante rm * .

  • Borrando de uno en uno. Bah... eso no es viable ya que hablamos de que hay quizás más de un millón de archivos a borrar!!
  • Creando un bucle for-do-done:

for i in ls /tmp/*; do rm -v $i -f; done

  • Usando find + xargs:

find . -name '*' | xargs rm

Es facil de entender este comando, pero no aporta gran mejora respecto a usar el bucle for-do-done. Para que aporte mejora podemos hacerlo algo mejor enviando, por ejemplo, de 10 en 10 archivos a xargs:


find ./ -name '*' -print0 | xargs -0 -n 10 rm

Con esto podremos borrar masivamente cualquier cantidad de archivos de una manera óptima. 

 



That u don't know what you've got 'til it's gone