1. トップ
  2. 新着ニュース
  3. IT
  4. IT総合

Windowsにおける環境変数をあらためて整理する

ASCII.jp / 2022年12月18日 10時0分

 Windowsを始め、Unixの影響を受けているOSが持つ機能に環境変数がある。環境変数は、実行するプログラムに対してなんらかの情報/パラメーターを与える方法。1979年に作られたVersion 7 Unixに搭載され、Unixの基本的な機能の1つとして今でも使われている。

環境変数ダイアログボックスでは、システム環境変数とユーザー環境変数を作成、編集することが可能だ

 プログラムに対して情報やなんらかのパラメーターを与える方法にはコマンドラインがあるが、環境変数は事前に定義しておくもので、複数回実行されるプログラムに常に同じ情報/パラメーターを指定する。あるいは、デフォルト値のように常に情報/パラメーターを指定するといった使い方をすることが多い。

 典型的なUnix系のコンソールアプリケーションでは、コマンドラインのオプション指定の一部を環境変数から受け取ることができるものが多い。

 Windowsでも、cmd.exeの組み込みコマンドである「dir」は、「DIRCMD」という環境変数からコマンドラインと同じオプション指定を受け取ることができる。これを使うと、起動時にオプションをすべて省略したときの動作を環境変数に指定しておくことができる。

 たとえば、以下のコマンドを実行すると、名前の逆順にファイルのリストを出力する。

set DIRCMD=/O-N dir

 詳細は、“dir /?”で表示されるオンラインヘルプを参照してほしい。

 環境変数はシェルでも頻繁に使われる。以下の表にシェルごとのプロセス環境変数の使い方を示す。

Windowsにおける環境変数の仕組み

 Windowsの環境変数は大きく3つの種類がある。「システム環境変数」「ユーザー環境変数」「プロセス環境変数」だ。システム環境変数はマシン内のすべてのユーザーに共通の環境変数、ユーザー環境変数はユーザーごとの環境変数だ。この2つはレジストリに記録されており、起動時に合成されて「プロセス環境変数」になる。このときの合成では、ユーザー環境変数の値が優先され、同名の環境変数があれば、ユーザー環境変数の値が使われる(例外あり)。

 すべてのプロセス(UWPアプリを除く)は、プロセス環境変数を親プロセスから受け継ぐ。親プロセスが環境変数を変更しなければ、それは、システム/ユーザー環境変数を合成したものがそのまま使われる。

 コマンドプロンプトやPowerShellなどの「シェル」プログラムには環境変数を表示・変更する機能がある。こうしたプログラムでは環境変数を変更したのち、子プロセスとしてプログラムを起動できる。このプログラムは、シェルで変更された環境変数を受け継ぐ。

 シェルで環境変数を書き換え、プログラムを実行したとき、プログラムは書き換えられた環境変数を参照することになる。ただし、環境変数を使うかどうかはプログラム次第である。前述のDIRのように環境変数を使うプログラムもあれば、そうでないプログラムもある。参照する環境変数名もプログラムにより異なる。

 環境変数は、「環境変数名」と「値」から構成される。どちらも文字列で、環境変数名はアルファベットと数字および一部の記号(コマンドラインで意味を持つ記号を除く)が利用できる。基本的にはファイル名と同じと考えてかまわない。ただし「=」は環境変数名に使うことはできない。

 1つの環境変数のサイズは64KB以内という制限があるが、実際には、設定するシェルなどの制限(たとえば1行の長さの最大値など)を受ける。

 プロセス環境変数は、「環境変数ブロック」と呼ばれるメモリ内の領域に記録される。過去のWindowsでは、この環境変数ブロックの大きさに制限があったが、Windows 10/11ではその制限はない。

 環境変数ブロックは、親プロセスの環境変数ブロックのコピーである。ただし、プロセスが終了すると環境変数ブロックは廃棄されてしまう。子プロセスから親プロセスに対して環境変数を使ってなにか情報を伝達することはできない。環境変数による情報の伝達は、常に親から子プロセスへの一方通行である。

 また、環境変数ブロックは、プロセスの起動時に親から受け取るため、起動後の「システム/ユーザー環境変数」の変更を受け取ることはできない。原則として環境変数は起動時点のままとなる。

 このため、CMD.EXEなどでは、システム/ユーザー環境変数が更新されたらプロセスを終了し、新規に起動する必要がある。注意する必要があるのは、Windows Terminalのように複数のシェルを起動可能な端末ソフトウェアを使う場合だ。Windows Terminalで実行されるCMD.EXEは、親がWindows Terminalとなるため、新規にCMD.EXEを起動しても、受け取るプロセス環境変数は同じものになる。これは、Windows Terminalが起動時に受け取ったプロセス環境変数がそのまま使われるからだ。

実際に環境変数を設定する

 システム/ユーザー環境変数を設定するには、「設定」→「システム」→「バージョン情報」→「関連リンク:システムの詳細設定」で表示される「システムのプロパティ」ダイアログの「環境変数」ボタンで「環境変数」ダイアログボックスを開く(記事冒頭画面)。

 かなり深いところにあって操作が面倒だが、以下のコマンドを使うと簡単に開くことができる。

C:\Windows\system32 undll32.exe sysdm.cpl, EditEnvironmentVariables

 これをショートカットやBatchファイルで作っておくと起動が楽になる。

ショートカットを作成すれば、簡単に環境変数ダイアログボックスを開くことができるようになる

 システム、ユーザー環境変数をコマンドラインから直接変更、追加するには、setx.exeコマンドを使うことができる。基本的な書式は、

setx.exe 環境変数名 値 [/M]

である。最後に「/M」を付けると「システム環境変数」の設定(要管理者権限)、付けなければユーザー環境変数の設定である。なお、setx.exeではシステム/ユーザー環境変数を表示することはできない。

 システム環境変数は、レジストリの

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment

に記録されており、ユーザー環境変数は、

HKEY_CURRENT_USER\Environment

に記録されている。

 PowerShellからシステム/ユーザー環境変数にアクセスする場合には、以下のコマンドが利用できる。

[System.Environment]::GetEnvironmentVariable(〈変数名〉,〈対象〉)

 ここで〈対象〉は、システム環境変数のとき「"Machine"」、ユーザー環境変数のときには「"User"」を指定する。変数を定義/変更するには「[Environment]::SetEnvironmentVariable”」を使う。

 WSLのbashなど、Linuxのシェルでは、.bashrcなどのシェルの初期化ファイルで環境変数をすべて定義する(詳しくはシェルのmanページを参照のこと)。たとえば、bashならばユーザーディレクトリにある「.basrc」(ユーザーごとでWindowsのユーザー環境変数に相当)や「/etc/bash.bashrc」(ユーザー共通でシステム環境変数に相当)などである。

システム/ユーザー環境変数を実行中のシェルに反映させる

 PowerShellでシステム/ユーザー環境変数を書き換えた場合、上記のコマンドを使って特定の環境変数を再読込させることもできる。1つのコマンドですべての環境変数を更新させることはできないが、1つの環境変数だけならば、以下のコマンドで再設定が可能だ。

$env:〈変数名〉=[System.Environment]::GetEnvironmentVariable(〈変数名〉,〈対象〉)

 WSLのbashの場合には、組み込みコマンドであるsourceコマンドを使って、.bashrcなどを再度読み込む。詳細は、bash-builtinsのmanページを参照してほしい。

 環境変数は、Unix/Linux系のOSを使っているユーザーやDOS時代からのユーザーにはなじみ深いものだが、GUIユーザーには必ずしもそうではない。しかし一部ではあるが、GUIアプリケーションでも環境変数を参照するものがある。また、コマンドラインを使うときに環境変数というものがあり、一部のコマンドは環境変数を見て動作を決定することは知っておいたほうがいいだろう。

この記事に関連するニュース

トピックスRSS

ランキング

記事ミッション中・・・

10秒滞在

記事にリアクションする

記事ミッション中・・・

10秒滞在

記事にリアクションする

デイリー: 参加する
ウィークリー: 参加する
マンスリー: 参加する
10秒滞在

記事にリアクションする

次の記事を探す

エラーが発生しました

ページを再読み込みして
ください