GNU/Linux >> Tutoriales Linux >  >> Linux

Error de lista de argumentos demasiado larga para comandos rm, cp, mv

Otra respuesta es forzar xargs para procesar los comandos en lotes. Por ejemplo a delete los archivos 100 a la vez, cd en el directorio y ejecuta esto:

echo *.pdf | xargs -n 100 rm


tl;dr

Es una limitación del kernel en el tamaño del argumento de la línea de comando. Usa un for bucle en su lugar.

Origen del problema

Este es un problema del sistema, relacionado con execve y ARG_MAX constante. Hay mucha documentación al respecto (ver man execve, wiki de debian, detalles de ARG_MAX).

Básicamente, la expansión produce un comando (con sus parámetros) que supere el ARG_MAX limit.On kernel 2.6.23 , el límite se estableció en 128 kB . Esta constante ha sido incrementada y puedes obtener su valor ejecutando:

getconf ARG_MAX
# 2097152 # on 3.5.0-40-generic

Solución:Usar for Bucle

Usa un for loop como se recomienda en BashFAQ/095 y no hay límite excepto por RAM/espacio de memoria:

Realice una ejecución en seco para asegurarse de que eliminará lo que espera:

for f in *.pdf; do echo rm "$f"; done

Y ejecutarlo:

for f in *.pdf; do rm "$f"; done

Además, este es un enfoque portátil ya que glob tiene un comportamiento fuerte y consistente entre los shells (parte de la especificación POSIX).

Nota: Como se ha señalado en varios comentarios, esto es más lento pero más fácil de mantener, ya que puede adaptarse a escenarios más complejos, p. ej. donde uno quiere hacer más que una sola acción.

Solución:Usar find

Si insistes, puedes usar find pero realmente no uses xargs ya que "es peligroso (roto, explotable, etc.) al leer entradas no delimitadas por NUL" :

find . -maxdepth 1 -name '*.pdf' -delete 

Usando -maxdepth 1 ... -delete en lugar de -exec rm {} + permite find simplemente ejecutar el sistema requerido se llama a sí mismo sin usar un proceso externo, por lo tanto, más rápido (gracias al comentario de @chepner).

Referencias

  • Obtengo "Lista de argumentos demasiado larga". ¿Cómo puedo procesar una lista grande en trozos? @ borde de lana
  • execve(2) - página del manual de Linux (busque ARG_MAX);
  • Error:lista de argumentos demasiado larga @ wiki de Debian;
  • ¿Por qué aparece "/bin/sh:lista de argumentos demasiado larga" cuando paso argumentos citados? @ superusuario

find tiene un -delete acción:

find . -maxdepth 1 -name '*.pdf' -delete

La razón por la que esto ocurre es porque bash en realidad expande el asterisco a cada archivo coincidente, produciendo una línea de comando muy larga.

Prueba esto:

find . -name "*.pdf" -print0 | xargs -0 rm

Advertencia: esta es una búsqueda recursiva y también encontrará (y eliminará) archivos en subdirectorios. Agrega -f al comando rm solo si está seguro de que no desea confirmación.

Puede hacer lo siguiente para que el comando no sea recursivo:

find . -maxdepth 1 -name "*.pdf" -print0 | xargs -0 rm

Otra opción es usar el -delete de find bandera:

find . -name "*.pdf" -delete

Linux
  1. Hoja de trucos para los comandos comunes de Linux

  2. 10 comandos de Linux para diagnóstico de red

  3. Ubuntu – ¿Lista de argumentos demasiado larga?

  4. ¿Grep para cadenas múltiples en archivos y luego listar los archivos en orden de tamaño?

  5. Comandos de búsqueda de Linux

Comandos de FreeDOS para fanáticos de Linux

¿Cómo limitar la profundidad para la lista de archivos recursivos?

Error SFTP Mensaje recibido demasiado largo

bash:/bin/tar:lista de argumentos demasiado larga al comprimir muchos archivos con tar

pd:el comando completo es demasiado largo

¿Cómo puedo eliminar todos los archivos de un directorio cuando informa que la lista de argumentos es demasiado larga?