批处理文件无法在条件语句中设置环境变量

时间:2021-06-09 23:21:37

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