Ich fand, dass dies den Fehler "Argument zu lang" auslösen würde:
ls *.*
Und das würde es nicht erhöhen:
for file in *.*
do
echo $file
done
Warum?
Ich fand, dass dies den Fehler "Argument zu lang" auslösen würde:
ls *.*
Und das würde es nicht erhöhen:
for file in *.*
do
echo $file
done
Warum?
Antworten:
Der Fehler "Argument zu lang" wird E2BIG
vom execve
Systemaufruf ausgelöst, wenn die Gesamtgröße der Argumente (plus der Umgebung auf einigen Systemen) zu groß ist. Der execve
Aufruf ist derjenige, der externe Prozesse startet, insbesondere das Laden einer anderen ausführbaren Datei (es gibt einen anderen Aufruf fork
, um einen separaten Prozess auszuführen, dessen Code immer noch aus derselben ausführbaren Datei stammt). Die for
Schleife ist ein internes Shell-Konstrukt und beinhaltet keinen Aufruf execve
. Der Befehl ls *.*
löst den Fehler nicht aus, wenn der Glob erweitert wird, sondern wenn er ls
aufgerufen wird.
execve
schlägt mit dem Fehler fehl, E2BIG
wenn die Gesamtgröße der Argumente für den Befehl größer als das ARG_MAX
Limit ist . Mit dem Befehl können Sie den Wert dieses Grenzwerts auf Ihrem System anzeigen getconf ARG_MAX
. (Es ist möglich, dass Sie diese Grenze überschreiten können, wenn Sie über genügend Speicher verfügen. Halten Sie die ARG_MAX
Garantien ein, execve
die funktionieren, solange kein Fehler auftritt.)
execve
Limit wird vom Kernel erzwungen, es setzt Limits, da die Argumente an einer Stelle über den Kernelspeicher kopiert werden müssen und Benutzerprozesse keine beliebige Menge an Shell-Speicher anfordern dürfen. Innerhalb der Shell gibt es keinen Grund, ein Limit zu haben. Alles, was in den virtuellen Speicher passt, ist in Ordnung.
Ich nehme an, dass im ersten Beispiel über einen / pair-Systemaufruf ausgeführt wird, im zweiten Beispiel ls
ist die gesamte Arbeit intern .bash
fork
exec
bash
Der exec
Aufruf hat Grenzen, die interne Arbeitsweise bash
stattdessen nicht (oder besser gesagt, hat verschiedene Grenzen, die nichts damit zu tun haben exec
, vielleicht die Menge des verfügbaren Speichers).
exec
in der /usr/include/linux/limits.h
Regel definiert als ARG_MAX
.
Denn im Falle ls
ist es ein Argument, und die Anzahl der Argumente ist begrenzt.
Im Falle des for
Zyklus handelt es sich nur um eine Liste von Elementen. Dafür gibt es (soweit mir bekannt ist) keine Grenzen.
for i in {00000001..20000000} ;do ((10#$i==1)) && break; done
/bin/bash
vs./bin/sh
(was ist vielleicht ein Link zum Bindestrich)?