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

Gio*_*Gio 67 linux shell environment-variables

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

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

sig*_*ice 68

我不认为Linux上存在每环境变量限制.所有环境变量的总大小限制在execve()时间.请参见"关于参数和环境大小的限制" 这里了解更多信息.

进程可以使用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;
}
Run Code Online (Sandbox Code Playgroud)

  • [askUbuntu的最佳答案(由Chipaca提供)](http://askubuntu.com/questions/14081/what-is-the-maximum-length-of-command-line-arguments-in-gnome-terminal)讨论使用`xargs --show-limits`获取更多信息. (9认同)
  • execve()信息为+1.您实际上可以添加最多(至少)8M的环境变量,但exec()调用将不起作用.无论何时尝试运行命令,这都会在bash中显示为"参数列表太长". (5认同)

pax*_*blo 21

好吧,我的盒子上至少有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
Run Code Online (Sandbox Code Playgroud)

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

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


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

  • 不,因此“感到无聊”位。Vi 模式命令行编辑使它变得更容易一些,但我认为它可能会在我达到 4M 标记之前失败。这就是生活。 (2认同)

小智 21

这里有两个有用的命令:

  • getconf -a | grep ARG_MAX

  • true | xargs --show-limits


cyb*_*ird 6

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

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

在我的盒子(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
Run Code Online (Sandbox Code Playgroud)

所以:极限很高!

  • 18446744071562068096 字节约为 15 艾字节。:) 与 512MiB 相比,这似乎是一个巨大的跳跃。 (2认同)
  • @Marcus:它是......我猜想不知何故1Gb即1073741824字节即2^30字节在某处溢出。错误18446744071562068096中的字节数非常接近2^64,即18446744073709551616 (2认同)
  • 我的 C/gdb 技能确实有限,但我认为问题出在 bash 源文件 subst.c 函数 sub_append_string (第 726 行)使用名为 n 的有符号 int 变量来计算新大小。新的大小 (2^31) 适合,但有一个对齐计算:“n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE);”,我怀疑该部分:“(n + DEFAULT_ARRAY_SIZE)”溢出。一切都很好,但我们当然远远超出了这里的任何理智限制。 (2认同)