OSで利用できる環境変数のサイズやPATHの長さには制限がある。その制限と回避方法などについて解説する。R2解説コマンドプロンプト上でコマンドを実行する場合、入力されたコマンド名がフルパス名で指定されていなければ、PATH環境変数で指定されている各フォルダーからコマンドが検索され、実行される。OSをインストールした直後のPATH環境変数には、%SystemRoot%以下のいくつかのフォルダーしか登録されておらず、非常にシンプルな内容になっている。Proのインストール直後のデフォルトのPATH環境変数の内容例。非常にシンプルであるC:\>pathPATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\C:\>だが多くのアプリケーションをインストールしたり、システムの更新などを繰り返したりしていると、実行ファイルや関連するデータファイルなどがさまざまな場所に配置されていく。結果としてPATHやそれ以外の環境変数の総数やサイズがどんどん増えてくる。実は環境変数のサイズには制限があり、これが問題を引き起こすことがある。表面化しやすい問題は、PATH環境変数の値が長くなりすぎていくつかのパスがカットされ、コマンドを見つけられなくなる、という不具合だろう。OSのエディションなどにもよるが、ほとんどの場合はPATH環境変数の最大長は約2000文字以下に制限されている。これを超えるようなPATH文字列を設定しても途中で切り捨てられてしまう。OSにおける環境変数の仕組みとその制限、回避方法などについてまとめておく。コマンドプロンプトの操作方法が分からない場合は、TIPS「これだけは覚えておきたいWindowsのコマンドプロンプトの使い方」を参照していただきたい。OSにおける環境変数とは、変数の「名前」とその「値」を文字列を組にして(「VAR=VALUE」のようにする)、さらにそれらをひとまとめにしたもの(=「環境変数ブロック」と言う)のことである。コマンドプロンプト上で「set」コマンドを実行すると、その一覧が表示される。OSの「プロセス」ごとに固有の情報であり、その初期値は、親プロセスの環境変数の内容を全て引き継いだものである。子プロセス内で環境変数の内容を変更しても、それは親プロセスへは伝達されない。環境変数には、「1つの変数当たり最大32,767文字まで」(Unicodeなので、バイト数で言えば最大64Kbytesまで)という制限がある。全ての環境変数を合計したサイズ(環境変数ブロックの最大サイズ)は、OSの技術的には特に制限はなく、利用可能なメモリサイズで制限される。XPなどの古いOSでは総サイズが最大32,767文字までに制限されていた。var1=C:\Windows」のようにして実行する。コマンドプロンプトでは1行当たり「最大で8190文字しか入力できない」ので、これを超えるような長いsetコマンドは実行できない。<変数名>=」というコマンド文字列も必要なので、結局コマンドプロンプト上で設定可能な環境変数のサイズは、最長でも約8180文字程度に制限されることになる。var=%longvar1%;%longvar2%;%longvar3%」のようにして8000文字を超えさせようとしてもエラーとなる。コマンドライン中の環境変数を展開した時点で内部の作業用バッファーが溢れるからである。環境変数の「展開後」のサイズが8000文字を超えるようなコマンドも実行できない。......変数の参照を使って、8000文字を超えるような長いコマンドを実行させてみる入力行が長すぎます。......変数の展開に失敗したので実行できないC:\>●環境変数のサイズ制限3:システム環境変数やユーザー環境変数の最大値は約2000文字まで環境変数は親プロセスから継承される。それでは最初のプロセス(各ユーザーのルートとなるプロセス)の環境変数はどうなっているかというと、これには以下の2つの初期値が用意されている。各ユーザーの環境変数には、これら2つの初期値を合成したものが設定される。ユーザーがシステムにサインインすると、まず「システム環境変数」がユーザーのルートとなるプロセスに設定される。その後、さらに「ユーザー環境変数」の値が設定されるので、最終的には2種類の環境変数の値を全て合成したものが設定されることになる。「PATH」環境変数については特別な処理が行われる。最初にシステム環境変数のPATHの値が設定された後、ユーザー環境変数側のPATHの値が「;」で区切って「追加」されるようになっている。これにより、システム全体で共通のPATH設定をベースにして、ユーザーごとの独自のコマンドパスも簡単に追加できるようになっている。システム環境変数とユーザー環境変数は、「システムのプロパティ」画面やsetxコマンドを使って設定することができる(ただしsetxコマンドでは変数の値として最大1024文字までしか設定できない。それ以上の長い文字列は切り捨てられる)。具体的な設定方法については次のTIPSを参照していただきたい。環境変数の初期値は、「システムのプロパティ」画面で確認、設定できる。8以降なら[Windows]+[X]キーで[システム]を選択してコントロールパネルの「システム」を表示させ、左側のメニューから[システムの詳細設定]のリンクをクリックする。(1)「システムのプロパティ」画面を表示させる。(2)[詳細設定]タブを選択する。(3)[環境変数]ボタンをクリックする。(4)上側がユーザーごとの環境変数。サインイン(ログオン)したユーザー固有の情報。システム環境変数の設定後に、こちらの環境変数の初期化が行われる。(5)下側がシステム全体で共通の環境変数。最初にシステムが起動したときに設定される。(6)TMPやTEMPは一時データ保存用のフォルダー。システム環境変数側にもTMPやTEMPがある。このように同じ名前の環境変数が両方にある場合は、ユーザー環境変数によって値が上書き設定される。ここに設定できる文字列の長さには制限がある。これらの画面では、環境変数の初期値を設定できる。ここで設定できる環境変数は、「最大でも2047文字まで」に制限されている(変数の値欄には2048文字以上入力できない)。そのため、システムの初期値として設定できるPATHは、システム環境変数PATHの約2000文字とユーザー環境変数PATHの約2000文字を加えた、約4000文字までとなる。実際の運用では、システム環境変数のPATHがメインで、ユーザー環境変数のPATHは補助的にしか使わないだろうから、システムのプロパティ画面で設定できるPATHの最大長は(システム環境変数のPATHによる)約2000文字までと考えておけばよいだろう。上の画面で環境変数の値を入力する場合、例えば「C:\MyProgram;D:\MyTools」のように直接フルパスを記述するだけでなく、「%myprg%;%mytool%」のように、別の環境変数を参照するような文字列を設定することもできる(myprgやmytoolも環境変数として定義しておくこと)。このような表記が使われている場合は、システムが最初に環境変数を評価する時(最初に環境変数ブロックを作成する時)に展開される。すると短い文字列でより長い値を表現できるので(一種の間接参照になる)、値としては2000文字しか入力できなくても、最終的な環境変数の値は、もっと長いパス文字列にできる。この方法を使っても、最終的に展開される結果の文字列の長さは最大で8190文字程度までに制限されるようである(制限を超えると途中で文字列が強制的にカットされる。場合によっては隣の環境変数とくっついてしまって、検索が正しく行えなくなることがあるので注意)。この環境変数の参照の展開処理は最初に1回しか行われない。最終的なPATHの中に%myvar%のような文字列が入っていた場合、コマンドの実行時にこれが動的に展開されることはないし、myvarの指す先のフォルダーからコマンドが検索されることもない。■[補足2]ユーザー環境変数からシステム環境変数を参照するもしシステム環境変数とユーザー環境変数に同じ名前の変数があった場合は(PATH変数以外)、後者のもので上書き設定されるので、ユーザー環境変数の設定内容が優先されることになる。PATH変数のように、システム環境変数の内容を引き継いだまま、別の値を追加したいなら、例えば「%var%;c:\newpath」のようにすればよい(VARという名前の変数が両方にある場合)。すれば、最初にシステム環境変数のVARの値がセットされた後、その末尾に「c:\newpath」が追加される。●結論:最終的なPATHの制限は約2000文字と想定すべき以上、環境変数の値(文字列)の長さを制約する3つの制限についてみてきた。これら3つの要件を満たすことを考えると、安全に利用可能なPATHの最大長は約2000文字と想定しておくべきだろう。システム環境変数のPATHとユーザー環境変数のPATHは別のものなので、必要なPATH文字列をこの2つの環境変数にうまく割り振ったり、%var%のような間接的な参照表記を使ったりすれば、もっと長いPATHが利用できる。このような細工はトラブルの元となるのでおすすめできない。システム環境変数のPATHは、アプリケーションのインストーラーなどが操作することも多いので、知らないうちに変更されていることが多く、不用意にいじるべきではない。メールマガジンをご購読ください。申し込みページへITmediaはアイティメディア株式会社の登録商標です。