Windowsバッチの遅延環境変数について

OXゲームバッチの修正をしててどうしても判らんかったのでちょっとテストした。

頭に setlocal ENABLEDELAYEDEXPANSION って書いて、即時展開は%hoge%、遅延展開は!hoge!、ってとこまでは判ったけれど、冒頭で定義したのとif文中で上書きしたのを同じように扱いたい場合はどうしたら良いのだろう。

まずは普通に。%RANDOM%で取得した変数によって、事前に定義した変数どれか一つを書き換えるバッチ。

@echo off

setlocal
rem setlocal ENABLEDELAYEDEXPANSION

set NUM=0
set VAL=3

set A=hoge
set B=fuga
set C=piyo

echo %A%
echo %B%
echo %C%

echo どれか一つを書き換え

set NUM=%RANDOM%
set /a VAL=%NUM%%%3

echo if文中のecho
if %VAL% equ 0 (
set A=foo
echo %A%
echo %B%
echo %C%
) else if %VAL% equ 1 (
set B=bar
echo %A%
echo %B%
echo %C%
) else if %VAL% equ 2 (
set C=baz
echo %A%
echo %B%
echo %C%
)

echo 普通のecho
echo %A%
echo %B%
echo %C%

endlocal
pause
exit

 実行結果。

hoge
fuga
piyo
どれか一つを書き換え
if文中のecho
hoge
fuga
piyo
普通のecho
foo
fuga
piyo
続行するには何かキーを押してください . . . 

まあこうなるわな。 

if文の中だけ!にしてみる。

@echo off
setlocal
setlocal ENABLEDELAYEDEXPANSION

set NUM=0
set VAL=3

set A=hoge
set B=fuga
set C=piyo

echo %A%
echo %B%
echo %C%

echo どれか一つを書き換え

set NUM=%RANDOM%
set /a VAL=%NUM%%%3

echo if文中のecho
if %VAL% equ 0 (
set A=foo
echo !A!
echo !B!
echo !C!
) else if %VAL% equ 1 (
set B=bar
echo !A!
echo !B!
echo !C!
) else if %VAL% equ 2 (
set C=baz
echo !A!
echo !B!
echo !C!
)

echo 普通のecho
echo %A%
echo %B%
echo %C%

endlocal
pause
exit

実行結果。

hoge
fuga
piyo
どれか一つを書き換え
if文中のecho
hoge
bar
piyo
普通のecho
hoge
bar
piyo
続行するには何かキーを押してください . . .

おお、上書きしてないのも!で展開出来るのね。

次は全部!にしてみる。

@echo off
setlocal
setlocal ENABLEDELAYEDEXPANSION

set NUM=0
set VAL=3

set A=hoge
set B=fuga
set C=piyo

echo %A%
echo %B%
echo %C%

echo どれか一つを書き換え

set NUM=%RANDOM%
set /a VAL=%NUM%%%3

echo if文中のecho
if %VAL% equ 0 (
set A=foo
echo !A!
echo !B!
echo !C!
) else if %VAL% equ 1 (
set B=bar
echo !A!
echo !B!
echo !C!
) else if %VAL% equ 2 (
set C=baz
echo !A!
echo !B!
echo !C!
)

echo 普通のecho
echo !A!
echo !B!
echo !C!

endlocal
pause
exit

実行結果。

hoge
fuga
piyo
どれか一つを書き換え
if文中のecho
foo
fuga
piyo
普通のecho
foo
fuga
piyo
続行するには何かキーを押してください . . .

if文の外でも!で展開出来るようだ。

次、if文をcallで外出ししてみる。

@echo off
setlocal
setlocal ENABLEDELAYEDEXPANSION

set NUM=0
set VAL=3

set A=hoge
set B=fuga
set C=piyo

echo %A%
echo %B%
echo %C%

echo どれか一つを書き換え

set NUM=%RANDOM%
set /a VAL=%NUM%%%3

call testcall.bat

echo 普通のecho
echo !A!
echo !B!
echo !C!

endlocal
pause
exit

testcall.batの中身

@echo off

echo if文中のecho
if %VAL% equ 0 (
set A=foo
echo !A!
echo !B!
echo !C!
) else if %VAL% equ 1 (
set B=bar
echo !A!
echo !B!
echo !C!
) else if %VAL% equ 2 (
set C=baz
echo !A!
echo !B!
echo !C!
)

実行結果。

hoge
fuga
piyo
どれか一つを書き換え
if文中のecho
hoge
fuga
baz
普通のecho
hoge
fuga
baz
続行するには何かキーを押してください . . .

callでも問題なく!で展開出来ている。

callの方に setlocal ENABLEDELAYEDEXPANSION も不要っぽいなあ。

遅延環境変数の場合、! は % の上位存在だと思っていいのだろうか。