Antworten:
Dies hängt stark vom System und der Version, von der Anzahl und Größe der Argumente sowie von der Anzahl und Größe der Umgebungsvariablennamen ab.
Traditionell lag das Limit (wie von Unix angegeben getconf ARG_MAX
) mehr oder weniger bei der kumulierten Größe von:
'\0'
)'\0'
), wobei eine Umgebungszeichenfolge gemäß Konvention so etwas wie ist var=value
.Denken Sie daran, dass dies cp
auch als Argument gilt (ist das erste Argument).
Unter Linux hängt es von der Version ab. Das Verhalten dort hat sich kürzlich geändert, wo es kein fester Raum mehr ist.
Bei der Überprüfung unter Linux 3.11 wird getconf ARG_MAX
jetzt ein Viertel des für die Stapelgröße festgelegten Grenzwerts angegeben (128 KB, wenn dies weniger als 512 KB sind).
( zsh
Syntax unten):
$ limit stacksize
stacksize 8MB
$ getconf ARG_MAX
2097152
$ limit stacksize 4M
$ getconf ARG_MAX
1048576
Diese Grenze liegt in der kumulativen Größe der Argument- und Umgebungszeichenfolgen und in einem gewissen Overhead (ich vermute aufgrund der Berücksichtigung der Ausrichtung an den Seitengrenzen). Die Größe der Zeiger wird nicht berücksichtigt.
Auf der Suche nach dem Limit bekomme ich:
$ /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
Die maximale kumulative Größe vor dem Brechen in diesem Fall ist:
$ (env _=/bin/true x=;print -l /bin/true {1..164686}) | wc -c
1044462
Das bedeutet nicht, dass Sie 1 Million leere Argumente übergeben können. Auf einem 64-Bit-System ergeben 1 Million leere Argumente eine Zeigerliste von 8 MB, was über meiner Stapelgröße von 4 MB liegen würde.
$ IFS=:; /bin/true ${=${(l.1000000..:.)${:-}}}
zsh: killed /bin/true ${=${(l.1000000..:.)${:-}}}
(Sie werden feststellen, dass es sich nicht um einen E2BIG-Fehler handelt. Ich bin mir nicht sicher, an welchem Punkt der Prozess dort abgebrochen wird, wenn er sich innerhalb des execve
Systemaufrufs oder später befindet.)
Beachten Sie auch (immer noch unter Linux 3.11), dass die maximale Größe eines einzelnen Arguments oder einer Umgebungszeichenfolge 128 KB beträgt, unabhängig von der Größe des Stapels.
$ /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
Nummer gekommen? dh wie haben Sie berechnet, dass die Sequenz unter der 2097152
Größe ARG_MAX liegen würde ?
Dies hängt vom Wert von ARG_MAX ab, der sich zwischen den Systemen ändern kann. So ermitteln Sie den Wert für Ihren Systemlauf (zeigen Sie das Ergebnis auf meinem als Beispiel):
$ getconf ARG_MAX
2097152
Dies hat nichts mit cp
Ihrer Shell zu tun. Es ist eine vom Kernel auferlegte Grenze. Es werden keine ( exec()
) Befehle ausgeführt, wenn ihre Argumente länger als sind ARG_MAX
. Wenn also die Länge der Argumentliste, die Sie angegeben haben, cp
größer als ARG_MAX ist, wird der cp
Befehl überhaupt nicht ausgeführt.
Um Ihre Hauptfrage zu beantworten, cp
werden keine Dateien verarbeitet, da sie niemals mit so vielen Argumenten ausgeführt werden. Ich sollte auch erwähnen, dass dies nicht von der Anzahl der Argumente abhängt, sondern von ihrer Länge. Möglicherweise haben Sie das gleiche Problem mit sehr wenigen, aber sehr langen Dateinamen.
Um diese Fehler zu umgehen, führen Sie Ihren Befehl in einer Schleife aus:
for file in /src/*; do cp "$file" /dst/; done
C
Probleme mit ARG_MAX und wirklich langen Dateinamen haben können?
IFS="\n" for file in /src/*; do mv "$file" /dst/; done
oder verwendenrsync -a /src/ /dst/
.