はじめに
この前ハマったので書いておく。
結論からすれば、よくハマると言われる遅延環境変数の問題だったわけですが、遅延環境変数は知っていたのですがFOR文のとき使用するものと思い込んでいて、IF文でも同様だったことに気がつかなかった。
下記の記事を見つけてやっと解決できたわけです。
バッチファイル。IF文やFOR文の中で複数コマンドを書く時の注意点 - Windowsのコマンドプロンプト(bat,cmd)
例
サブルーチン内で変数の値を変更し、if内でその変数の値を使用しようとした際にハマりました。
変数なら駄目なのかとサブルーチンの戻り値として「exit /b 値」として、%errorlevel% で使用しようとしても同じでした。
@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 enabledelayedexpansion
とendlocal
で囲む - 遅延評価したい環境変数は
%
ではなく!
で囲む
今回はif内括弧の echo if内hoge=!hoge!
に変更しています。
@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文の括弧内で代入した変数の値を参照する方法」にしようと思ったのですが、代入や参照というキーワードでは検索されないと思ったのでやめました。