28.9.11

/bin/rm: Argument list too long - Como solucionarlo.

hoy me volvi a encontrar con este problema y me decidi a escibir una entrada para los q se lo encuentran x 1era vez... la 1era vez suele ser traumatica... xD

uno de los servers en los q trabajo esta todo el tiempo bajando datos q almacena en un directorio del sistema generando una gran cantidad de archivos q se van acumulando bastante rapido. dado q no uso personalmente los datos y no tengo muy claro hasta cuando sirven, suelo dejar q se acumulen hasta q el espacio en disco empieza a escasear y ahi es cuando viene el problema. la cantidad de archivos es tan grande q al intentar algo tan simple como un rm *.* la consola me devuelve:

/bin/rm: Argument list too long


el problema

como decia antes suele ser bastante traumatico encontrarse con q no se puede hacer algo tan basico como borrar archivos. buscando tanto la solucion como la causa me encontre con la interesante explicacion de que no es un problema del comando en si sino del kernel de linux.

traduccion de la debian wiki:

el limite afecta la funcion execve() del kernel, q es usada x todas las otras 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. entonces el kernel carga el nuevo programa en memoria, setea 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.

x suerte el usuario normal no tiene q luchar normalmente con directorios q contienen tantos archivos... entonces me dio curiosidad de ver de cuantos archivos hablamos en realidad (mientras escribo esto voy haciendo el proceso), entonces meto en la consola:

# ls | wc -l

... y despues de un buen rato me devuelve... 1146724!!


la solucion

para poder borrar los archivos lo q tenemos q hacer es pasarselos a rm como argumento de a poco usando xargs. la linea q recomienda la misma debian wiki es esta:

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

hacemos un find de todos los archivos (*) y x medio de xargs se los vamos pasando a rm de a 10 (-n 10). el "-print0" en find y el -0 en xargs son para no tener problemas con los espacios en blanco de los archivos si es q los tienen, sino se pueden eliminar.

hay otras soluciones posibles como ls | xargs rm o ir borrando x partes pero la anterior es la mas simple y efectiva.