Windows批处理中IF语句内的SET命令无效

129

当我运行这个脚本(从一个 .bat 文件):

set var1=true
if "%var1%"=="true" (
  set var2=myvalue
  echo %var2%
)

我总是得到:

ECHO is on.

意思是说var2变量并没有真正被设置。 有人可以帮我理解为什么吗?

2个回答

247

变量var2已经被设置,但是在执行代码块之前,行内的echo %var2%中却没有展开该变量。
此时,var2还是个空值。

因此,引入了延迟执行语法,它使用!代替%,在执行时而不是解析时进行求值。

请注意,为了使用!,需要额外添加语句setlocal EnableDelayedExpansion

setlocal EnableDelayedExpansion
set var1=true
if "%var1%"=="true" (
  set var2=myvalue
  echo !var2!
)

15
谢谢你,你刚刚帮我避免了巨大的痛苦。 - Myna
2
&&&运算符遵循相同的规则。这段代码set x=some & set y=%x%thing & echo results %y%输出%x%thing - gwarah
使用像FOR这样的循环命令、复合或括号表达式,延迟扩展将允许您始终读取变量的当前值。[1] 此外,为了显示括号是方括号,使用括号-方括号...在括号代码块内部使用GOTO命令将打破括号上下文... [2] (强调我的)。我认为在ifbatch上搜索明确的信息真的很难,尽管我已经搜索了足够多的内容来学习如果jeb(没有!)说它,那就一定是对的。 - ruffin

21

我可能有点晚来参加这个派对,但处理这种情况的另一种方法是在 if 之外继续处理,就像这样:

set var1=true
if "%var1%"=="true" (
    set var2=myvalue
)
echo %var2%

或/和使用goto语法

set var1=true
if "%var1%"=="true" (
    set var2=myvalue
    goto line10
) else (
    goto line20
)
. . . . .
:line10
echo %var2%
. . . . . 
:line20

这种扩展是在时间内发生的,您不需要使用setlocal EnableDelayedExpansion。总的来说,如果重新思考脚本的设计,您可以这样做。

这样扩展就会“按时间”发生,您不需要使用setlocal EnableDelayedExpansion。归根结底,如果重新考虑脚本的设计,您可以这样做。


1
我无法访问在if语句中创建的变量。您的第一个var2示例不起作用。 - AntonioCS
@AntonioCS 很有意思...这是我刚测试过的确切脚本:echo off set var1=true if "%var1%"=="true" ( set var2=myvalue ) echo %var2% pause.. 而且它是有效的。*"如果您在批处理文件中创建一个可以在程序中任何地方访问的变量"*. https://aticleworld.com/batch-file-variables-and-scope/ - T.S.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接