Réponses:
Cela dépend grandement du système et de la version, du nombre et de la taille des arguments et du nombre et de la taille des noms de variables d'environnement.
Traditionnellement sur Unix, la limite (telle que rapportée par getconf ARG_MAX
) était plus ou moins sur la taille cumulée de:
'\0'
)'\0'
), une chaîne d'environnement étant par convention quelque chose comme var=value
.Gardant à l'esprit que cela cp
compte également comme argument (est le premier argument).
Sous Linux, cela dépend de la version. Le comportement a changé récemment là où ce n'est plus un espace fixe.
La vérification sous Linux 3.11, getconf ARG_MAX
rapporte désormais un quart de la limite définie sur la taille de la pile, ou 128 ko si c'est moins de 512 ko).
( zsh
syntaxe ci-dessous):
$ limit stacksize
stacksize 8MB
$ getconf ARG_MAX
2097152
$ limit stacksize 4M
$ getconf ARG_MAX
1048576
Cette limite est sur la taille cumulée des chaînes d'argument et d'environnement et certains frais généraux (je soupçonne en raison de la considération d'alignement sur les limites de page). La taille des pointeurs n'est pas prise en compte.
En cherchant la limite, j'obtiens:
$ /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
La taille cumulée maximale avant rupture dans ce cas est:
$ (env _=/bin/true x=;print -l /bin/true {1..164686}) | wc -c
1044462
Maintenant, cela ne signifie pas que vous pouvez passer 1 million d'arguments vides. Sur un système 64 bits, 1 million d'arguments vides font une liste de pointeurs de 8 Mo, ce qui serait supérieur à ma taille de pile de 4 Mo.
$ IFS=:; /bin/true ${=${(l.1000000..:.)${:-}}}
zsh: killed /bin/true ${=${(l.1000000..:.)${:-}}}
(vous aurez remarqué que ce n'est pas une erreur E2BIG. Je ne sais pas à quel moment le processus y est tué, si c'est dans l' execve
appel système ou plus tard).
Notez également (toujours sous Linux 3.11) que la taille maximale d'un seul argument ou chaîne d'environnement est de 128 Ko, quelle que soit la taille de la pile.
$ /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
numéro? c'est-à-dire comment avez-vous calculé que la séquence serait 2097152
inférieure à la taille ARG_MAX?
Cela dépendra de la valeur de ARG_MAX qui peut changer entre les systèmes. Pour connaître la valeur de l'exécution de votre système (en montrant le résultat sur le mien à titre d'exemple):
$ getconf ARG_MAX
2097152
Cela n'a rien à voir avec cp
ou votre shell, c'est une limite imposée par le noyau, il n'exécutera pas de exec()
commandes ( ) si leurs arguments sont plus longs que ARG_MAX
. Ainsi, si la longueur de la liste d'arguments à laquelle vous avez donné cp
est supérieure à ARG_MAX, la cp
commande ne s'exécutera pas du tout.
Pour répondre à votre question principale alors, cp
ne traitera aucun fichier car il ne sera jamais exécuté avec autant d'arguments. Je dois également mentionner que cela ne dépend pas du nombre d'arguments mais de leur longueur. Vous pourriez éventuellement avoir le même problème avec des noms de fichiers très rares mais très longs.
La façon de contourner ces erreurs consiste à exécuter votre commande en boucle:
for file in /src/*; do cp "$file" /dst/; done
C
ARG_MAX peuvent avoir des problèmes et des noms de fichiers très longs?
IFS="\n" for file in /src/*; do mv "$file" /dst/; done
oursync -a /src/ /dst/
.