这是损坏的批处理文件:
@echo off
if prod==prod (
if xps==xps (
set i1=prodxpsi1
set i2=prodxpsi2
set e1=prodxpse1
set e2=prodxpse2
) else (
set i1=prodzpsi1
set i2=prodzpsi2
set e1=prodzpse1
set e2=prodzpse2
)
if 1==1 (
echo %i1%, %i2%, %e1%, %e2%
) else (
echo %i1%, %i2%, %e1%, %e2%
)
)
pause
Run Code Online (Sandbox Code Playgroud)
但是,当我if prod==prod像这样取出外部块时,它可以工作:
@echo off
if xps==xps (
set i1=prodxpsi1
set i2=prodxpsi2
set e1=prodxpse1
set e2=prodxpse2
) else (
set i1=prodzpsi1
set i2=prodzpsi2
set e1=prodzpse1
set e2=prodzpse2
)
if 1==1 (
echo %i1%, %i2%, %e1%, %e2%
) else (
echo %i1%, %i2%, %e1%, %e2%
)
pause
Run Code Online (Sandbox Code Playgroud)
当我第一次运行批处理文件时,它回显, , ,. 当我第二次运行它时,它工作正常:

这是命令解析器的一个怪癖。由于括号的存在,它将从if ...到的所有内容都)视为一行。当它读取此“一行”时,它会在处理任何变量之前将所有变量扩展为其值。这些set命令都发生在变量被扩展之后。
有两种解决方案:分支和延迟扩展。
分支:确保set命令和echo命令不在同一组最顶层括号中:
@echo off
if not prod==prod goto :end
if xps==xps (
set ...
) else (
set ...
)
if 1==1 (
...
)
:end
pause
Run Code Online (Sandbox Code Playgroud)
延迟扩展:这会导致变量按需扩展,而不是提前扩展。使用命令SetLocal EnableDelayedExpansion激活此模式,使用!标记以这种方式引用变量,并EndLocal在完成后使用该命令。请注意,EndLocal不会忘记任何变量后声明SetLocal,所以你可能要移动SetLocal到后set命令。
@echo off
setlocal enabledelayedexpansion
if prod==prod (
if xps==xps (
set i1=prodxpsi1
...
) else (
set i1=prodzpsi1
...
)
if 1==1 (
echo !i1!, !i2!, !e1!, !e2!
) else (
echo !i1!, !i2!, !e1!, !e2!
)
)
endlocal
pause
Run Code Online (Sandbox Code Playgroud)