CMD.EXEの遅延環境変数

2006/12/10 新規作成

客先でハマッた奴らが3名。忘れないようにここに記す。

( ) の中の遅延環境変数

以下のようなバッチファイルを書いて実行する。

 C:\workfold>type chk.bat
 @ECHO OFF
 SET A=1
 ECHO 1..[%A%]
 (
   SET A=2
   ECHO 2..[%A%]
 )
 ECHO 3..[%A%]
 
 
 C:\workfold>chk.bat

実行結果は以下のようになる。

 C:\workfold>chk.bat
 1..[1]
 2..[1]
 3..[2]
 C:\workfold>

ここで、

 1..[1]
 2..[2]
 3..[2]

と予想した人が多いかもしれない。筆者もその一人。
( )内の 変数 A が予想に反し 書き換わっていない(様に見える)
( )内を実行終了後、書き換わっているようだ。
この振る舞いを遅延環境変数と称する様である。

遅延環境変数のからくり

からくりとしては、( ) 内を実行する前に、 ( ) 内で展開可能な環境変数を全て展開し、それから実行する。 例えば、先の例の

 (
   SET A=2
   ECHO 2..[%A%]
 )

は、先に“A=1”と定義されている為に

 (
   SET A=2
   ECHO 2..[1]   ←ここ。%A%が1に置き換わっている
 )

と置換えが起こり、この状態で実行される。
この 置換え完了後の ( ) 実行で初めて 変数 A が 2 に変更される。 「遅延環境変数」とは環境変数自体の性質を指すものではなく、( ) 内の置換規則のことを指しているのである。

しかし、名称があまりよろしくない。 あたかも「遅延」という性質を持った環境変数があるかのような錯覚を起こしてしまう。