Вопрос по shell, linux – Каков максимальный размер значения переменной среды?

63

Существует ли ограничение на количество данных, которые могут храниться в переменной среды в Linux, и если да, то что это?

Для Windows я обнаружил следующееСтатья кб который сводится к:   Windows XP или более поздняя версия: 8191 символов   Windows 2000 / NT 4.0: 2047 символов

Фактический предел для окон составляет 31 767. Вы читаете оset команда, которая имеет ограничение командной строки до 8191 символа.See this msdn article  Тем не менее, случайное ограничение. Christopher Currens
8191 - это не случайно. Это 2 ^ 13 - 1. Barnaby Dawson

Ваш Ответ

6   ответов
61

Я не думаю, что в Linux существует ограничение на количество переменных для каждой среды. Общий размер всех переменных среды вместе взятых ограничен во время execve (). Смотрите & quot; Ограничения на размер аргументов и среды & quot;Вот для дополнительной информации.

Процесс может использовать setenv () или putenv () для расширения среды за пределы исходного пространства, выделенного exec.

Вот быстрая и грязная программа, которая создает переменную окружения 256 МБ.

#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 для execve () информация. Вы можете добавить переменные окружения до (как минимум) 8M, но вызовы exec () не будут работать. Это проявляется в bash как "список аргументов слишком длинный" всякий раз, когда вы пытаетесь запустить команду.
The top answer (by Chipaca) on askUbuntu обсуждает использованиеxargs --show-limits чтобы получить больше информации.
Также обратите внимание, что POSIX требует, чтобы ARG_MAX был по крайней мере _POSIX_ARG_MAX, который должен быть 4096.
такksh is different?
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, Если оноdoesn't начинается с@, он использует значение самой переменной среды.


Интересно, что со всеми этими установленными переменными каждая команда начинает жаловаться на то, что список аргументов слишком длинный, поэтому, даже если он позволяет их задавать, он может не иметь возможности запускать программы после того, как вы это сделали (поскольку передать среду для этих программ).

Нет, следовательно, "скучно" немного. Редактирование командной строки в Vi-режиме сделало это немного легче, но я подумал, что оно может потерпеть неудачу, прежде чем я достигну отметки 4M. C 'est la vie.
ноwhy do ksh variables stop at 256K? возможноCentOS тоже
Я надеюсь, что вы использовали сценарий и не печатали все это вручную!
@ L & # x1B0; uV & # x129; nhPh & # xFA; c: потому что программы имеют ограничения. Они могут быть произвольными пределами или основаны на доступных ресурсах, но ограничения существуют. Вполне возможно, DavidK предположил, что его оболочка не будет (неправильно) использоваться сумасшедшими, которые должны знать лучше :-)
1

Я использовал этот очень быстрый и грязный php-код (ниже), изменив его для различных значений, и обнаружил, что он работает для переменных длин до 128k. После этого по какой-либо причине он не работает; исключение не возникает, об ошибках не сообщается, но значение не отображается в подоболочке.

Может быть, это ограничение php? Может быть, есть настройки php.ini, которые могут повлиять на это? Или, может быть, существует ограничение на размер переменных, которые наследует подоболочка? Возможно, есть соответствующие настройки ядра или оболочки.

В любом случае, по умолчанию в CentOS ограничение для установки переменной среды с помощью putenv в php составляет около 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";
?>

Информация о версии -

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

Не знаю точно, но быстрый эксперимент показывает, что ошибки не возникает, например, со значением 64 КБ:

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

Итак: предел довольно высок!

0

Командная строка (со всеми аргументами) плюс переменная окружения должны быть меньше 128k.

Нужна цитата

Похожие вопросы