2009-05-18 101 views
14

为什么下面的Windows批处理文件输出Foo followedby Bar,而不是Baz批处理文件未能条件语句中设置环境变量

@echo off 
setlocal 

set _=Foo 
echo %_% 
set _=Bar 
if 1==1 (
    set _=Baz 
    echo %_% 
) 

我的系统上的输出(微软的Windows XP [版本5.1.2600)是:

Foo 
Bar 

如果我删除了条件语句中,FooBaz预期输出观察。

+0

重复的http://stackoverflow.com/questions/305605/weird-scope-issue-in-bat-file – 2009-05-18 11:43:12

回答

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"

+2

真棒,感谢您的详细解释。我想我再一次反对这个确切的限制,但是在这个更受限制的环境中:http://stackoverflow.com/questions/879023/honoring-exit-codes-from-batch-files-invoked-by- msbuild不幸的是,我没有能力打开命令扩展,如果我使用MSBuild`Exec`任务...嗯... – 2009-05-18 18:06:03

3

试试这个

@echo off 
setlocal 

set _=Foo 
echo %_% 
set _=Bar 
if "1" NEQ "2" goto end 
set _=Baz 
echo %_% 
:end 
4

这个问题的答案是一样的答案:Weird scope issue in batch file。请参阅此处了解更多详情。基本上可变扩展是在线路读取时完成的,而不是在执行时间。

相关问题