为什么以下Windows批处理文件输出Foo
后跟Bar
,而不是Baz
?
@echo off
setlocal
set _=Foo
echo %_%
set _=Bar
if 1==1 (
set _=Baz
echo %_%
)
我系统上的输出(Microsoft Windows XP [版本5.1.2600])是:
Foo
Bar
如果删除条件语句,则会观察Foo
和Baz
的预期输出。
答案 0 :(得分:28)
正在发生的是在读取行时完成变量替换。你没有考虑到的是:
if 1==1 (
set _=Baz
echo %_%
)
是一个“行”,尽管您可能会想到。 "%_%"
的扩展在 set
语句之前完成。
您需要的是延迟扩张。几乎每一个命令脚本都以"setlocal enableextensions enabledelayedexpansion"
开头,以便使用cmd.exe
的全部功能。
所以我的脚本版本是:
@echo off
setlocal enableextensions enabledelayedexpansion
set _=Foo
echo !_!
set _=Bar
if 1==1 (
set _=Baz
echo !_!
)
endlocal
这会生成正确的"Foo", "Baz"
而不是"Foo", "Bar"
。
答案 1 :(得分:4)
答案与Weird scope issue in batch file的答案相同。查看更多详情。基本上可变扩展是在行读取时完成的,而不是在执行时完成的。
答案 2 :(得分:3)
试试这个
@echo off
setlocal
set _=Foo
echo %_%
set _=Bar
if "1" NEQ "2" goto end
set _=Baz
echo %_%
:end