コマンドプロンプトの遅延環境変数

コマンドプロンプトで FOR ループなどを使っているときに 「あれ? 変数の値が変わらない??」ということがあります。

例えば、バッチファイルに次のように書いてあるとします。

FOR /F %%i IN ('SET') DO ECHO %%i 

これは、コマンド SET の実行結果をずらっと表示します。

この結果の件数を取得するためにカウンタを付けたとします。

SET COUNT=0
FOR /F %%i IN ('SET') DO SET /A COUNT=%COUNT%+1
ECHO %COUNT% 

上手く行きそうなのですが、結果は 1 が出力されます。

これは変数の“即時展開”というもので、 ループの中の %COUNT% が先に評価されてしまうので 結果的には次のような処理になってしまうためです。

SET COUNT=0
FOR /F %%i IN ('SET') DO SET /A COUNT=0+1
ECHO %COUNT% 

対応として“遅延環境変数”を使うという方法があります。

遅延環境変数は、名前の通り遅延して変数を評価してくれるわけですが デフォルトではオフ、CMD.exe のオプションやレジストリの変更や SETLOCAL での指定が必要になります。
(詳しくは CMD /? してください)

今回は SETLOCAL を使って見ます。

次のように SETLOCAL で enabledelayedexpansion を指定して ENDLOCAL で終わります。 ( ENDLOCAL は省略可です。)

さらに遅延評価する変数は "%" ではなく "!" で囲みます。

SETLOCAL enabledelayedexpansion
SET COUNT=0
FOR /F %%i IN ('SET') DO SET /A COUNT=!COUNT!+1
ECHO %COUNT%
ENDLOCAL

これで想定していた結果が返ります。
(試す場合はファイルに保存して実行してください)

遅延環境変数を使わないで CALL を使う方法もあります。

SET COUNT=0
FOR /F %%i IN ('SET') DO CALL SET /A COUNT=%%COUNT%%+1
ECHO %COUNT%

これでも同じ結果が返ります。
CALL の中で "%" が二重になっていることに注意してください。

Google サイト内検索

Amazonアソシエイト