Why does the following Windows Batch File output Foo
followedby Bar
, rather than Baz
?
为什么以下Windows批处理文件输出Foo后跟Bar而不是Baz?
@echo off
setlocal
set _=Foo
echo %_%
set _=Bar
if 1==1 (
set _=Baz
echo %_%
)
The output on my system (Microsoft Windows XP [Version 5.1.2600]) is:
我的系统上的输出(Microsoft Windows XP [版本5.1.2600])是:
Foo
Bar
If I remove the conditional statement, the expected output of Foo
and Baz
is observed.
如果我删除条件语句,则会观察到Foo和Baz的预期输出。
3 个解决方案
#1
What's happening is that variable substitution is done when a line is read. What you're failing to take into account is the fact that:
发生的事情是在读取行时完成变量替换。你没有考虑到的事实是:
if 1==1 (
set _=Baz
echo %_%
)
is one "line", despite what you may think. The expansion of "%_%"
is done before the set
statement.
尽管你可能会想到,但这是一条“线”。 “%_%”的扩展在set语句之前完成。
What you need is delayed expansion. Just about every single one of my command scripts starts with "setlocal enableextensions enabledelayedexpansion"
so as to use the full power of cmd.exe
.
你需要的是延迟扩张。几乎每一个命令脚本都以“setlocal enableextensions enabledelayedexpansion”开头,以便使用cmd.exe的全部功能。
So my version of the script would be:
所以我的脚本版本是:
@echo off
setlocal enableextensions enabledelayedexpansion
set _=Foo
echo !_!
set _=Bar
if 1==1 (
set _=Baz
echo !_!
)
endlocal
This generates the correct "Foo", "Baz"
rather than "Foo", "Bar"
.
这会生成正确的“Foo”,“Baz”而不是“Foo”,“Bar”。
#2
The answer to this is the same as the answer to:Weird scope issue in batch file. See there for more details. Basically variable expansion is done at line read time, not at execution time.
对此的答案与答案相同:批处理文件中的奇怪范围问题。在那里查看更多详情。基本上可变的扩展是在行读取时完成的,而不是在执行时完成的。
#3
try this
@echo off
setlocal
set _=Foo
echo %_%
set _=Bar
if "1" NEQ "2" goto end
set _=Baz
echo %_%
:end
#1
What's happening is that variable substitution is done when a line is read. What you're failing to take into account is the fact that:
发生的事情是在读取行时完成变量替换。你没有考虑到的事实是:
if 1==1 (
set _=Baz
echo %_%
)
is one "line", despite what you may think. The expansion of "%_%"
is done before the set
statement.
尽管你可能会想到,但这是一条“线”。 “%_%”的扩展在set语句之前完成。
What you need is delayed expansion. Just about every single one of my command scripts starts with "setlocal enableextensions enabledelayedexpansion"
so as to use the full power of cmd.exe
.
你需要的是延迟扩张。几乎每一个命令脚本都以“setlocal enableextensions enabledelayedexpansion”开头,以便使用cmd.exe的全部功能。
So my version of the script would be:
所以我的脚本版本是:
@echo off
setlocal enableextensions enabledelayedexpansion
set _=Foo
echo !_!
set _=Bar
if 1==1 (
set _=Baz
echo !_!
)
endlocal
This generates the correct "Foo", "Baz"
rather than "Foo", "Bar"
.
这会生成正确的“Foo”,“Baz”而不是“Foo”,“Bar”。
#2
The answer to this is the same as the answer to:Weird scope issue in batch file. See there for more details. Basically variable expansion is done at line read time, not at execution time.
对此的答案与答案相同:批处理文件中的奇怪范围问题。在那里查看更多详情。基本上可变的扩展是在行读取时完成的,而不是在执行时完成的。
#3
try this
@echo off
setlocal
set _=Foo
echo %_%
set _=Bar
if "1" NEQ "2" goto end
set _=Baz
echo %_%
:end