Qual è la dimensione massima di un valore di una variabile d’ambiente?

Esiste un limite alla quantità di dati che possono essere memorizzati in una variabile d’ambiente su Linux, e in tal caso: che cos’è?

Per Windows, ho trovato il seguente articolo della Knowledge Base che riassume: Windows XP o successivo: 8191 caratteri Windows 2000 / NT 4.0: 2047 caratteri

Non penso che ci sia un limite di variabili per ambiente su Linux. La dimensione totale di tutte le variabili ambientali messe insieme è limitata al tempo execve (). Vedi “Limiti sulla dimensione degli argomenti e dell’ambiente” qui per ulteriori informazioni.

Un processo può usare setenv () o putenv () per far crescere l’ambiente oltre lo spazio iniziale allocato da exec.

Ecco un programma veloce e sporco che crea una variabile di ambiente da 256 MB.

 #include  #include  #include  #include  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; } 

Bene, è almeno 4M sulla mia scatola. A quel punto mi sono annoiato e ho smesso di camminare. Speriamo che l’uscita del terminale sia finita prima che torni al lavoro lunedì 🙂

 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 

Se sei preoccupato che 4M potrebbe non essere sufficiente per la tua variabile di ambiente, potresti voler ripensare a come stai facendo le cose.

Forse sarebbe una buona idea mettere le informazioni in un file e poi usare una variabile d’ambiente per fare riferimento a quel file. Ho visto casi in cui, se la variabile è della forma @/path/to/any/fspec , ottiene le informazioni effettive dal path/to/any/fspec del file path/to/any/fspec . Se non inizia con @ , utilizza il valore della variabile di ambiente stessa.


È interessante notare che con tutte queste variabili impostate, ogni singolo comando inizia a lamentarsi del fatto che l’elenco degli argomenti è troppo lungo, quindi, anche se consente di impostarli, potrebbe non essere in grado di avviare programmi dopo averlo fatto (poiché deve passare l’ambiente a quei programmi).

Ho fatto un rapido test sulla mia macchina Linux con il seguente frammento:

 a="1" while true do a=$a$a echo "$(date) $(numfmt --to=iec-i --suffix=B --padding=7 ${#a})" done 

Sulla mia scatola (Gentoo 3.17.8-gentoo-r1) questo risulta in (ultime righe di output):

 Wed Jan 3 12:16:10 CET 2018 16MiB Wed Jan 3 12:16:11 CET 2018 32MiB Wed Jan 3 12:16:12 CET 2018 64MiB Wed Jan 3 12:16:15 CET 2018 128MiB Wed Jan 3 12:16:21 CET 2018 256MiB Wed Jan 3 12:16:33 CET 2018 512MiB xrealloc: cannot allocate 18446744071562068096 bytes 

Quindi: il limite è abbastanza alto!

Ho usato questo codice php molto veloce e sporco (sotto), modificandolo per valori diversi, e ho scoperto che funziona per lunghezze variabili fino a 128k. Dopo quello, per qualunque ragione, non funziona; non viene sollevata alcuna eccezione, non viene segnalato alcun errore, ma il valore non viene visualizzato nella sottoshell.

Forse questo è un limite specifico per PHP? Forse ci sono impostazioni php.ini che potrebbero influenzarlo? O forse c’è un limite alla dimensione di Vars che erediterà una subshell? Forse ci sono impostazioni di configurazione del kernel o della shell rilevanti.

Ad ogni modo, per impostazione predefinita, in CentOS, il limite per l’impostazione di var nell’ambiente tramite putenv in php sembra essere di circa 128k.

  

Informazioni sulla versione –

 [[email protected] scratch]# php --version PHP 5.2.6 (cli) (built: Dec 2 2008 16:32:08) <..snip..> [[email protected] 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 [[email protected] scratch]# cat /etc/redhat-release CentOS release 5.3 (Final) 

Non so esattamente, ma un rapido esperimento mostra che non si verifica alcun errore, ad es. Con 64kB di valore:

 % perl -e 'print "#include \nint main() { return setenv(\"FOO\", \"", "x"x65536, "\", 1); }\n";'\ | gcc -xc -o envtest - && ./envtest && echo $? 0 

La riga di comando (con tutti gli argomenti) più la variabile di ambiente dovrebbe essere inferiore a 128k.