环境变量值的最大大小是多少?

时间:2009-07-03 06:45:35

标签: linux shell environment-variables

Linux上的环境变量中可以存储的数据量是否有限制,如果是这样的话:它是什么?

对于Windows,我发现以下KB article总结为:   Windows XP或更高版本:8191个字符   Windows 2000 / NT 4.0:2047个字符

7 个答案:

答案 0 :(得分:63)

我认为Linux上没有每个环境的变量限制。所有环境变量的总大小限制在execve()时间。有关详细信息,请参阅“参数和环境大小的限制”here

进程可以使用setenv()或putenv()来扩展exec分配的初始空间之外的环境。

这是一个快速而又脏的程序,它创建了一个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;
}

答案 1 :(得分:20)

嗯,我的盒子上至少有4M。那时,我感到无聊,徘徊。希望终端输出在周一回到工作岗位之前完成: - )

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

如果您担心4M对于您的环境变量可能不够,您可能需要重新考虑您的工作方式。

将信息放入文件然后使用环境变量引用该文件可能更好。我见过这样的情况:如果变量的格式为@/path/to/any/fspec,它会从文件path/to/any/fspec中获取实际信息。如果@开头,则它使用环境变量本身的值。


有趣的是,在设置了所有这些变量之后,每个命令都会开始抱怨参数列表太长,所以即使它允许你设置它们,它也可能无法在你完成之后启动程序(从那以后)它必须将环境传递给那些程序。)

答案 2 :(得分:5)

我使用以下代码段在我的Linux机器上进行了快速测试:

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

在我的方框(Gentoo 3.17.8-gentoo-r1)上导致(最后一行输出):

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

所以:限制很高!

答案 3 :(得分:1)

不完全确切,但快速实验表明没有错误发生,例如64kB的价值:

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

答案 4 :(得分:1)

我使用这个非常快速和脏的PHP代码(下面),修改它为不同的值,并发现它适用于高达128k的可变长度。在那之后,无论出于何种原因,它都不起作用;没有引发异常,没有报告错误,但该值未显示在子shell中。

也许这是特定于php的限制?也许有php.ini设置可能会影响它?或者也许子shell将继承的变量大小有限制?也许有相关的内核或shell配置设置..

无论如何,默认情况下,在CentOS中,通过putenv在php中设置var的限制似乎大约是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";
?>

版本信息 -

[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)

答案 5 :(得分:0)

命令行(带有所有参数)加上环境变量应小于128k。

答案 6 :(得分:0)

非常有用的pause = False # pause state while True: ticks = pygame.time.get_ticks() for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() if event.type == KEYUP: if event.key == pygame.K_1 and not game_over: print("Next level") # toggle pause if "p" is pressed if event.key == pygame.K_p: pause = not pause # [...] if pause: # [...] draw pause screen pass elif not game_over: # <--- elif is important playing = True # [...] screen.blit(backbuffer, (0,0)) pygame.display.update() fpsclock.tick(30) getconf -a |grep MAX