Czy istnieje ograniczenie ilości danych, które można przechowywać w zmiennej środowiskowej w systemie Linux, a jeśli tak, to co to jest?
W przypadku systemu Windows znalazłem następujący artykuł KB, który podsumowuje: Windows XP lub nowszy: 8191 znaków Windows 2000 / NT 4.0: 2047 znaków
set
poleceniu, które ma limit linii poleceń do 8191 znaków. Zobacz ten artykuł w witrynie MSDN Jednak nadal jest to przypadkowe ograniczenie.Odpowiedzi:
Nie sądzę, że istnieje limit zmiennych środowiskowych w systemie Linux. Całkowity rozmiar wszystkich połączonych zmiennych środowiskowych jest ograniczony w
execve()
czasie. Aby uzyskać więcej informacji, zobacz „Ograniczenia dotyczące rozmiaru argumentów i środowiska” tutaj .Proces może wykorzystywać
setenv()
lubputenv()
rozszerzać środowisko poza początkową przestrzeń przydzieloną przez exec.Oto szybki i brudny program, który tworzy zmienną środowiskową 256 MB.
#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; }
źródło
xargs --show-limits
aby uzyskać więcej informacji.Cóż, na moim pudełku jest co najmniej 4M. W tym momencie znudziłem się i odszedłem. Mam nadzieję, że wyjście terminala zostanie zakończone, zanim wrócę do pracy w poniedziałek :-)
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
Jeśli martwisz się, że 4M może nie wystarczyć dla zmiennej środowiskowej, możesz przemyśleć, jak robisz.
Być może lepszym pomysłem byłoby umieszczenie informacji w pliku, a następnie użycie zmiennej środowiskowej do odniesienia się do tego pliku. Widziałem przypadki, w których, jeśli zmienna ma postać
@/path/to/any/fspec
, pobiera rzeczywiste informacje z plikupath/to/any/fspec
. Jeśli nie zaczyna się od@
, używa wartości samej zmiennej środowiskowej.Co ciekawe, gdy wszystkie te zmienne są ustawione, każde polecenie zaczyna narzekać, że lista argumentów jest zbyt długa, więc nawet jeśli pozwala je ustawić, może nie być w stanie uruchomić programów po wykonaniu tego (ponieważ musi przekazać środowisko do tych programów).
źródło
Zrobiłem szybki test na moim Linuksie z następującym fragmentem kodu:
a="1" while true do a=$a$a echo "$(date) $(numfmt --to=iec-i --suffix=B --padding=7 ${#a})" done
Na moim komputerze (Gentoo 3.17.8-gentoo-r1) daje to (ostatnie wiersze wyniku):
A więc: limit jest dość wysoki!
źródło
n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE);
i podejrzewam, że część:(n + DEFAULT_ARRAY_SIZE)
przepełnienia. Wszystko bardzo miłe, ale oczywiście jesteśmy tutaj poza wszelkimi rozsądnymi granicami ..Oto dwa pomocne polecenia:
getconf -a |grep MAX
true | xargs --show-limits
źródło
Nie wiem dokładnie, ale szybki eksperyment pokazuje, że żaden błąd nie występuje np. Przy 64kB wartości:
% perl -e 'print "#include <stdlib.h>\nint main() { return setenv(\"FOO\", \"", "x"x65536, "\", 1); }\n";'\ | gcc -x c -o envtest - && ./envtest && echo $? 0
źródło
Użyłem tego bardzo szybkiego i brudnego kodu php (poniżej), modyfikując go dla różnych wartości i stwierdziłem, że działa on dla zmiennych długości do 128k. Potem z jakiegoś powodu nie działa; nie jest zgłaszany żaden wyjątek, nie jest zgłaszany żaden błąd, ale wartość nie jest wyświetlana w podpowłoce.
Może to jest limit specyficzny dla php? Może są ustawienia php.ini, które mogą na to wpłynąć? A może istnieje ograniczenie rozmiaru zmiennych, które odziedziczy podpowłoka? Może są odpowiednie ustawienia konfiguracji jądra lub powłoki.
W każdym razie, domyślnie w CentOS limit ustawiania zmiennej w środowisku przez putenv w php wydaje się wynosić około 128k.
<?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"; ?>
Informacje o wersji -
[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)
źródło
Linia poleceń (ze wszystkimi argumentami) plus zmienna środowiskowa powinna być mniejsza niż 128 KB.
źródło