Gibt es eine Begrenzung für die Datenmenge, die in einer Umgebungsvariablen unter Linux gespeichert werden kann, und wenn ja: Was ist das?
Für Windows habe ich folgenden KB-Artikel gefunden, der Folgendes zusammenfasst: Windows XP oder höher: 8191 Zeichen Windows 2000 / NT 4.0: 2047 Zeichen
set
Befehl, dessen Befehlszeilenlimit auf 8191 Zeichen begrenzt ist. Siehe diesen msdn-Artikel. Trotzdem eine zufällige Einschränkung.Antworten:
Ich glaube nicht, dass es unter Linux ein Umgebungsvariablenlimit gibt. Die Gesamtgröße aller Umgebungsvariablen zusammen ist zeitlich begrenzt
execve()
. Weitere Informationen finden Sie hier unter "Beschränkungen der Größe von Argumenten und der Umgebung" .Ein Prozess kann die Umgebung über den von exec zugewiesenen anfänglichen Speicherplatz hinaus verwenden
setenv()
oder erweiternputenv()
.Hier ist ein schnelles und schmutziges Programm, das eine Umgebungsvariable mit 256 MB erstellt.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main(void) { size_t size = 1 << 28; /* 256 MB */ char *var; var = malloc(size); if (var == NULL) { perror("malloc"); return 1; } memset(var, 'X', size); var[size - 1] = '\0'; var[0] = 'A'; var[1] = '='; if (putenv(var) != 0) { perror("putenv"); return 1; } /* Demonstrate E2BIG failure explained by paxdiablo */ execl("/bin/true", "true", (char *)NULL); perror("execl"); printf("A=%s\n", getenv("A")); return 0; }
quelle
xargs --show-limits
, um weitere Informationen zu erhalten.Nun, es ist mindestens 4M auf meiner Box. Zu diesem Zeitpunkt langweilte ich mich und ging davon. Hoffentlich ist die Terminalausgabe fertig, bevor ich am Montag wieder bei der Arbeit bin :-)
export b1=A export b2=$b1$b1 export b4=$b2$b2 export b8=$b4$b4 export b16=$b8$b8 export b32=$b16$b16 export b64=$b32$b32 export b128=$b64$b64 export b256=$b128$b128 export b512=$b256$b256 export b1k=$b512$b512 export b2k=$b1k$b1k export b4k=$b2k$b2k export b8k=$b4k$b4k export b16k=$b8k$b8k export b32k=$b16k$b16k export b64k=$b32k$b32k export b128k=$b64k$b64k export b256k=$b128k$b128k export b512k=$b256k$b256k export b1m=$b512k$b512k export b2m=$b1m$b1m export b4m=$b2m$b2m echo $b4m AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA : : : : : : : : : : : : AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Wenn Sie befürchten, dass 4M für Ihre Umgebungsvariable nicht ausreicht, sollten Sie Ihre Arbeitsweise überdenken.
Vielleicht wäre es eine bessere Idee, die Informationen in eine Datei einzufügen und dann eine Umgebungsvariable zu verwenden, um auf diese Datei zu verweisen. Ich habe Fälle gesehen, in denen die Variable, wenn sie vom Formular ist
@/path/to/any/fspec
, die tatsächlichen Informationen aus der Datei erhältpath/to/any/fspec
. Wenn es nicht funktioniert mit beginnen@
, verwendet es den Wert der Umgebungsvariablen selbst.Interessanterweise beschwert sich bei jedem dieser Variablen jeder einzelne Befehl darüber, dass die Argumentliste zu lang ist. Obwohl Sie sie festlegen können, kann er möglicherweise keine Programme starten, nachdem Sie dies getan haben (da dies erforderlich ist) Weitergabe der Umgebung an diese Programme).
quelle
Ich habe einen kurzen Test auf meiner Linux-Box mit dem folgenden Snippet durchgeführt:
a="1" while true do a=$a$a echo "$(date) $(numfmt --to=iec-i --suffix=B --padding=7 ${#a})" done
Auf meiner Box (Gentoo 3.17.8-gentoo-r1) ergibt dies (letzte Ausgabezeilen):
Also: das Limit ist ziemlich hoch!
quelle
n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE);
und ich vermute das Teil:(n + DEFAULT_ARRAY_SIZE)
Überläufe. Alles sehr schön, aber wir sind hier natürlich weit über jede vernünftige Grenze hinaus.Hier sind zwei hilfreiche Befehle:
getconf -a |grep MAX
true | xargs --show-limits
quelle
Ich weiß es nicht genau, aber ein kurzes Experiment zeigt, dass kein Fehler auftritt, z. B. bei 64 KB Wert:
% perl -e 'print "#include <stdlib.h>\nint main() { return setenv(\"FOO\", \"", "x"x65536, "\", 1); }\n";'\ | gcc -x c -o envtest - && ./envtest && echo $? 0
quelle
Ich habe diesen sehr schnellen und schmutzigen PHP-Code (unten) verwendet, ihn für verschiedene Werte geändert und festgestellt, dass er für variable Längen bis zu 128 KB funktioniert. Danach funktioniert es aus irgendeinem Grund nicht mehr. Es wird keine Ausnahme ausgelöst, es wird kein Fehler gemeldet, aber der Wert wird nicht in der Unterschale angezeigt.
Vielleicht ist dies eine PHP-spezifische Grenze? Vielleicht gibt es php.ini-Einstellungen, die sich darauf auswirken könnten? Oder gibt es eine Begrenzung für die Größe von Vars, die eine Subshell erben wird? Möglicherweise gibt es relevante Kernel- oder Shell-Konfigurationseinstellungen.
Standardmäßig scheint in CentOS das Limit für das Festlegen einer Variable in der Umgebung über putenv in PHP bei 128 KB zu liegen.
<?php $s = 'abcdefghijklmnop'; $s2 = ""; for ($i = 0; $i < 8100; $i++) $s2 .= $s; $result = putenv('FOO='.$s2); print shell_exec('echo \'FOO: \'${FOO}'); print "length of s2: ".strlen($s2)."\n"; print "result = $result\n"; ?>
Versions Information -
[root@localhost scratch]# php --version PHP 5.2.6 (cli) (built: Dec 2 2008 16:32:08) <..snip..> [root@localhost scratch]# uname -a Linux localhost.localdomain 2.6.18-128.2.1.el5 #1 SMP Tue Jul 14 06:36:37 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux [root@localhost scratch]# cat /etc/redhat-release CentOS release 5.3 (Final)
quelle
Die Befehlszeile (mit allen Argumenten) und die Umgebungsvariable sollten kleiner als 128 KB sein.
quelle