バッチファイルでのsetの罠

@echo off

set IN=
set /P IN="XXXを入力 > "
echo %IN%

if "%IN%"=="XXX" (
	set /P IN="もう一度、値を入力 > "
	echo %IN%
)

echo %IN%

XXXを入力 > XXX
XXX
もう一度、値を入力 > YYY
XXX
YYY


どういうことなの・・・


set /? より。

    set VAR=before
    if "%VAR%" == "before" (
        set VAR=after;
        if "%VAR%" == "after" @echo If you see this, it worked
    )
この例は、論理的には IF 文が別の IF 文の本体に含まれる複合文なので、
両方の IF 文の %VAR% が、最初の IF 文を読み取ったときに展開されます。
このため、メッセージは決して表示されません。
複合文の中の IF では "before" と "after" が比較され、
決して等しくはなりません。


救いはないんですかァッ!!

遅延環境変数の展開では、実行時に環境変数を展開するために異なった文字
(感嘆符) を使うことができます。
遅延環境変数の展開が有効な場合、上記の
例は次のように書くと意図したように動作します。
    set VAR=before
    if "%VAR%" == "before" (
        set VAR=after
        if "!VAR!" == "after" @echo If you see this, it worked
    )


やむをえない!

@echo off

set VAR=before
if "%VAR%" == "before" (
    set VAR=after
    if "!VAR!" == "after" echo If you see this, it worked
)

Fuck You!!


デフォルトで「遅延環境変数の展開」ってのが有効になってるわけじゃないのか。

@echo off

SETLOCAL ENABLEDELAYEDEXPANSION

set VAR=before
if "%VAR%" == "before" (
    set VAR=after
    if "!VAR!" == "after" echo If you see this, it worked
)

If you see this, it worked


参考文献

SET /?
CMD /?
SETLOCAL /?