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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1078031/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:29:09  来源:igfitidea点击:

What is the maximum size of an environment variable value?

linuxshellenvironment-variables

提问by Gio

Is there a limit to the amount of data that can be stored in an environment variable on Linux, and if so: what is it?

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

For Windows, I've found following KB articlewhich summarizes to: Windows XP or later: 8191 characters Windows 2000/NT 4.0: 2047 characters

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

采纳答案by sigjuice

I don't think there is a per-environment variable limit on Linux. The total size of all the environment variables put together is limited at execve() time. See "Limits on size of arguments and environment" herefor more information.

我认为 Linux 上没有每个环境变量的限制。所有环境变量放在一起的总大小在 execve() 时间受到限制。有关更多信息,请参阅此处的“参数和环境大小的限制” 。

A process may use setenv() or putenv() to grow the environment beyond the initial space allocated by exec.

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

Here's a quick and dirty program that creates a 256 MB environment variable.

这是一个快速而肮脏的程序,它创建了一个 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] = '
% perl -e 'print "#include <stdlib.h>\nint main() { return setenv(\"FOO\", \"", "x"x65536, "\", 1); }\n";'\
| gcc -x c -o envtest - && ./envtest && echo $?
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; }

回答by laalto

Don't know exactly but a quick experiment shows that no error occurs e.g. with 64kB of value:

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

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

回答by J-16 SDiZ

The command line (with all argument) plus the environment variable should be less then 128k.

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

回答by paxdiablo

Well, it's at least 4M on my box. At that point, I got bored and wandered off. Hopefully the terminal output will be finished before I'm back at work on Monday :-)

嗯,我的盒子上至少有 4M。那一刻,我觉得无聊,就走开了。希望终端输出能在我周一回去工作之前完成:-)

<?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";
?>

If you're worried that 4M may not be enough for your environment variable, you may want to rethink how you're doing things.

如果您担心 4M 可能不足以容纳您的环境变量,您可能需要重新考虑您的工作方式。

Perhaps it would be a better idea to put the information into a file and then use an environment variable to reference that file. I've seen cases where, if the variable is of the form @/path/to/any/fspec, it gets the actual information from the file path/to/any/fspec. If it doesn'tbegin with @, it uses the value of the environment variable itself.

也许将信息放入文件中然后使用环境变量来引用该文件会是一个更好的主意。我见过这样的情况,如果变量的形式为@/path/to/any/fspec,它会从文件中获取实际信息path/to/any/fspec。如果不以开头@,则使用环境变量本身的值。



Interestingly enough, with all those variables set, every single command starts complaining that the argument list is too long so, even though it lets you set them, it may not be able to start programs after you've done it (since it has to pass the environment to those programs).

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

回答by Shavais

I used this very quick and dirty php code (below), modifying it for different values, and found that it works for variable lengths up to 128k. After that, for whatever reason, it doesn't work; no exception is raised, no error is reported, but the value does not show up in the subshell.

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

Maybe this is a php-specific limit? Maybe there are php.ini settings that might affect it? Or maybe there's a limit on the size of vars that a subshell will inherit? Maybe there are relevant kernel or shell config settings..

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

Anyway, by default, in CentOS, the limit for setting a var in the environment via putenv in php seems to be about 128k.

无论如何,默认情况下,在 CentOS 中,通过 php 中的 putenv 在环境中设置 var 的限制似乎约为 128k。

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

Version info -

版本信息 -

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

回答by cyberbird

I did a quick test on my Linux box with the following snippet:

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

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

On my box (Gentoo 3.17.8-gentoo-r1) this results in (last lines of output):

在我的机器上(Gentoo 3.17.8-gentoo-r1),这导致(输出的最后几行):

##代码##

So: the limit is quite high!

所以:限制相当高!

回答by dmitry_podyachev

Here are two helpful commands:

这里有两个有用的命令:

  • getconf -a |grep MAX

  • true | xargs --show-limits

  • getconf -a |grep MAX

  • true | xargs --show-limits