Respuestas:
Eso depende en gran medida del sistema y la versión, del número y el tamaño de los argumentos y del número y tamaño de los nombres de las variables de entorno.
Tradicionalmente en Unix, el límite (según lo informado por getconf ARG_MAX
) era más o menos en el tamaño acumulativo de:
'\0'
)'\0'
), siendo una cadena de entorno por convención algo así var=value
.Teniendo en cuenta que cp
también cuenta como argumento (es el primer argumento).
En Linux, depende de la versión. El comportamiento allí cambió recientemente donde ya no es un espacio fijo.
Comprobando en Linux 3.11, getconf ARG_MAX
ahora informa una cuarta parte del límite establecido en el tamaño de la pila, o 128 KB si es inferior a 512 KB).
( zsh
sintaxis a continuación):
$ limit stacksize
stacksize 8MB
$ getconf ARG_MAX
2097152
$ limit stacksize 4M
$ getconf ARG_MAX
1048576
Ese límite está en el tamaño acumulativo de las cadenas de argumento y entorno y algunos gastos generales (sospecho que debido a la consideración de alineación en los límites de la página). El tamaño de los punteros no se tiene en cuenta.
Buscando el límite, obtengo:
$ /bin/true {1..164686}
$ /bin/true {1..164687}
zsh: argument list too long: /bin/true
$ x= /bin/true {1..164686}
$ x=1 /bin/true {1..164686}
zsh: argument list too long: /bin/true
El tamaño acumulado máximo antes de romper en ese caso es:
$ (env _=/bin/true x=;print -l /bin/true {1..164686}) | wc -c
1044462
Ahora, eso no significa que pueda pasar 1 millón de argumentos vacíos. En un sistema de 64 bits, 1 millón de argumentos vacíos forman una lista de punteros de 8 MB, que estaría por encima de mi tamaño de pila de 4MiB.
$ IFS=:; /bin/true ${=${(l.1000000..:.)${:-}}}
zsh: killed /bin/true ${=${(l.1000000..:.)${:-}}}
(notará que no es un error E2BIG. No estoy seguro de en qué punto el proceso se anula allí si está dentro de la execve
llamada al sistema o más tarde).
También tenga en cuenta (todavía en Linux 3.11) que el tamaño máximo de un solo argumento o cadena de entorno es 128 KB, independientemente del tamaño de la pila.
$ /bin/true ${(l.131071..a.)${:-}} # 131072 OK
$ /bin/true ${(l.131072..a.)${:-}} # 131073 not
zsh: argument list too long: /bin/true
$ /bin/true ${(l.131071..a.)${:-}} ${(l.131071..a.)${:-}} # 2x 131072 OK
164686
número? es decir, ¿cómo calculó que la secuencia estaría por debajo del 2097152
tamaño ARG_MAX?
Eso dependerá del valor de ARG_MAX que puede cambiar entre sistemas. Para averiguar el valor de la ejecución de su sistema (que muestra el resultado en el mío como ejemplo):
$ getconf ARG_MAX
2097152
Esto no tiene nada que ver con cp
su shell, es un límite impuesto por el kernel, no ejecutará ( exec()
) comandos si sus argumentos son más largos que ARG_MAX
. Entonces, si la longitud de la lista de argumentos que ha dado cp
es mayor que ARG_MAX, el cp
comando no se ejecutará en absoluto.
Entonces, para responder a su pregunta principal, cp
no procesará ningún archivo, ya que nunca se ejecutará con tantos argumentos. También debo mencionar que esto no depende del número de argumentos sino de su longitud. Posiblemente podría tener el mismo problema con muy pocos pero muy largos nombres de archivo.
La forma de evitar estos errores es ejecutar su comando en un bucle:
for file in /src/*; do cp "$file" /dst/; done
C
pueden tener problemas con ARG_MAX y nombres de archivo realmente largos?
IFS="\n" for file in /src/*; do mv "$file" /dst/; done
orsync -a /src/ /dst/
.