web-dev-qa-db-ja.com

環境変数値の最大サイズは?

Linuxの環境変数に保存できるデータの量に制限はありますか?

Windowsの場合、次のように見つかりました KB article 要約すると、Windows XP以降:8191文字Windows 2000/NT 4.0:2047文字

67
Gio

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;
}
67
sigjuice

まあ、それは私の箱に少なくとも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から実際の情報を取得するケースを見てきました。 しない@で始まる場合、環境変数自体の値を使用します。


興味深いことに、これらすべての変数が設定されていると、すべてのコマンドが引数リストが長すぎると不平を言い始めます。環境をそれらのプログラムに渡します)。

21
paxdiablo

次のスニペットを使用して、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

だから、制限は非常に高いです!

6
cyberbird

正確にはわかりませんが、簡単な実験ではエラーが発生しないことが示されています。 64kBの値:

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

この非常に高速でダーティなphpコード(下記)を使用して、さまざまな値に変更しましたが、最大128kの可変長で機能することがわかりました。その後、何らかの理由で機能しません。例外は発生せず、エラーは報告されませんが、値はサブシェルに表示されません。

たぶんこれはPHP固有の制限ですか? php.iniの設定が影響する可能性がありますか?または、サブシェルが継承する変数のサイズに制限があるのでしょうか?おそらく、関連するカーネルまたはシェルの構成設定があります。

とにかく、CentOSのデフォルトでは、phpのputenvを介して環境に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)
1
Shavais

非常に役立ちます getconf -a |grep MAXまたはxargs --show-limits

1

コマンドライン(すべての引数を含む)と環境変数は、128k未満でなければなりません。

0
J-16 SDiZ