Posted at

【BAT】IF文やFOR文の括弧内で変更した変数の値を取得する方法


はじめに

この前ハマったので書いておく。

結論からすれば、よくハマると言われる遅延環境変数の問題だったわけですが、遅延環境変数は知っていたのですがFOR文のとき使用するものと思い込んでいて、IF文でも同様だったことに気がつかなかった。

下記の記事を見つけてやっと解決できたわけです。

バッチファイル。IF文やFOR文の中で複数コマンドを書く時の注意点 - Windowsのコマンドプロンプト(bat,cmd)


サブルーチン内で変数の値を変更し、if内でその変数の値を使用しようとした際にハマりました。

変数なら駄目なのかとサブルーチンの戻り値として「exit /b 値」として、%errorlevel% で使用しようとしても同じでした。


test.bat

@echo off

set hoge=0
set fuga=0

call :test

pause
exit

:test

if %fuga%==0 (
call :test2
echo if内hoge=%hoge%
)

echo hoge=%hoge%

exit /b

:test2
set hoge=1

exit /b


call :test2 で変更したhogeの値はif内では反映されません、括弧内で代入する前の値となります。

代入した値が有効になるのは、IF文やFOR文を抜けた直後となります。


想定している値

if内hoge=1

hoge=1


実際の値

if内hoge=0

hoge=1


対応

遅延環境変数を使用すればいい。



  • setlocal enabledelayedexpansionendlocal で囲む

  • 遅延評価したい環境変数は%ではなく! で囲む

今回はif内括弧の echo if内hoge=!hoge! に変更しています。


test.bat

@echo off

set hoge=0
set fuga=0

setlocal enabledelayedexpansion

call :test

endlocal

pause
exit

:test

if %fuga%==0 (
call :test2
echo if内hoge=!hoge!
)

echo hoge=%hoge%

exit /b

:test2
set hoge=1

exit /b


これで想定した結果となります。


実際の値

if内hoge=1

hoge=1


最後に

他のプログラム言語と同じように単なるグローバル変数だと思い込んでいるとハマりますね。

解決しようとしてネットで検索しようとしても、何のキーワードにすればいいんだって感じです。

今回タイトルを「IF文やFOR文の括弧内で代入した変数の値を参照する方法」にしようと思ったのですが、代入や参照というキーワードでは検索されないと思ったのでやめました。