環境変数値の最大サイズはいくつですか?


85

Linuxの環境変数に保存できるデータの量に制限はありますか?もしそうなら:それは何ですか?

Windowsの場合、次のKB記事を見つけました。要約は次のとおりです。WindowsXP以降:8191文字Windows 2000 / NT 4.0:2047文字


Windowsの実際の制限は31,767です。setコマンドラインの制限が8191文字であるコマンドについて読みました。 ただし、このmsdnの記事を参照してください。それでもランダムな制限です。
クリストファーカレンズ2012年

5
8191はそれほどランダムではありません。これは、2 ^ 13だ- 1
バーナビー・ドーソン

AWS Lambda:[環境変数の]セットの合計サイズが4 KBを超えない(ソース
MartinThoma19年

1
@BarnabyDawsonおそらくクリストファーはそれが恣意的であるという意味でそれを意味しましたか?
0xC0000022L

回答:


77

Linuxには環境ごとの変数制限はないと思います。まとめられたすべての環境変数の合計サイズは、execve()一度に制限されます。詳細については、こちらの「引数のサイズと環境の制限」を参照してください。

プロセスは、execによって割り当てられた初期スペースを超えて環境を使用setenv()またはputenv()拡張する場合があります。

これは、256MBの環境変数を作成する手っ取り早いプログラムです。


5
execve()情報の場合は+1。実際には(少なくとも)8Mまでの環境変数を追加できますが、exec()呼び出しは機能しません。これは、コマンドを実行しようとするたびに「引数リストが長すぎる」としてbashに現れます。
paxdiablo 2009

1
また、POSIXは、少なくとも4096でなければなりません_POSIX_ARG_MAX、ことARG_MAXが必要であることに注意してください
ninjalj

10
askUbuntuの(Chipacaによる)トップアンサーはxargs --show-limits、より多くの情報を得るために使用することについて議論しています。
docSalvager 2013

引数文字列ごとの制限も表示されます-「さらに、文字列ごとの制限は32ページです(カーネル定数MAX_ARG_STRLEN)」
kiran01bm19年

24

まあ、それは私の箱に少なくとも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。それは場合はしないで始まり@、それは環境変数自体の値を使用しています。


興味深いことに、これらすべての変数が設定されると、すべてのコマンドが引数リストが長すぎると文句を言い始めます。そのため、変数を設定できたとしても、実行後にプログラムを起動できない場合があります(それらのプログラムに環境を渡します)。


1
スクリプトを使用し、これをすべて手作業で入力しなかったことを願っています。
Chris Huang-Leaver

2
いいえ、したがって「退屈」ビット。Viモードのコマンドライン編集で少し簡単になりましたが、4Mマークに達する前に失敗するかもしれないと思いました。C'est lavie。
paxdiablo 2009

1
しかし、なぜksh変数は256Kで停止するのですか?おそらくCentOS
phuclv 2016年

@LưuVĩnhPhúc:プログラムには制限があるため。それらは任意の制限である場合もあれば、利用可能なリソースに基づく場合もありますが、制限は存在します。おそらくDavidKは、自分のシェルが、もっとよく知っているはずの
狂信

7

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

だから:制限はかなり高いです!


1
18446744071562068096バイトは約15エクサバイトです。:)それは512MiBからの大きなジャンプのようです。
マーカス

1
@マーカス:それは...どういうわけか1Gb、つまり1073741824バイト、つまり2 ^ 30バイトがどこかにオーバーフローしていると思います。エラー18446744071562068096のバイト数は2 ^ 64にかなり近い、つまり18446744073709551616
サイバーバード

1
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)がオーバーフローしているのではないかと思い ます。すべて非常に素晴らしいですが、もちろんここでは正気の限界をはるかに超えています
。–サイバーバード

3

ここに2つの役立つコマンドがあります:

  • getconf -a |grep MAX

  • true | xargs --show-limits


〜100の変数のどれが関連していますか?それらはどこに文書化されていますか?
ingomueller.net

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

1

私はこの非常に速くて汚い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)

0

コマンドライン(すべての引数を含む)と環境変数は、128k未満である必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.