Windows批处理变量无法设置

51

我认为我遇到了Windows批处理脚本中的一个错误。

我无法设置在扩展if语句中的变量。

这是我的脚本的一个独立部分:

@echo off

set success=1
set Version=12345
set Target=Client
set Type=456
set dir=
set zip=

if "%Version%"=="" set success=0
if "%Type%"=="" set success=0

if 1==1 set test=42

if %success%==1 (
    set test2=57005
    if "%Target%"=="Client" (
        set dir=ModName v%Version%
        set zip=ModName v%Version% %Type%.zip
        echo Version: %Version%
        echo    Type: %Type%
        echo.
        echo  Target: %Target%
        echo     dir: %dir%
        echo     zip: %zip%
        echo.
        echo    test: %test%
        echo   test2: %test2%
    )
) else (
    echo Not successful.
)

这是从全新的cmd实例中输出的内容:

C:\Users\RandomClown\Desktop>test.bat
Version: 12345
   Type: 456

 Target: Client
    dir:
    zip:

   test: 42
  test2:

你需要注意的是单行if语句正确地设置了内容。 多行if将执行任何不是set的内容。我认为我没有漏掉任何东西。 此外,多行if语句正确地执行了正确的代码行,因为else ( echo Not successful. )没有被执行。

为什么这些行没有执行?


7
可能是windows batch SET inside IF not working的重复问题。 - chwarr
2个回答

94

你漏了点什么;-)

cmd 在解析命令时扩展变量,而不是在运行命令时。碰巧,在这种情况下,带有块 ( ... )(或实际上任何块)的iffor语句在这种情况下算作单个命令。因此,当您在块内设置变量并尝试在同一块中使用它们时,就没有变量了 - 它们被替换为变量在块甚至执行之前就有的值。

添加一个

setlocal enabledelayedexpansion

在批处理文件的开头使用!zip!代替%zip%。有关该问题的详细讨论,请参见help set


1

提醒一下,MS-DOS的“set”命令会接受等号后面的所有字符串。因此,如果您写入

if "x"=="x" set a=foo else set a=bar
echo %a%  // output : foo else set a=bar

%a%实际上被设置为“否则设置a=bar”,而不是foo。因此,如果一行中有多个命令,我总是使用“()”进行设置命令。

if "%1"=="" (set a=20) else (set a=%1)    

2
“set” 命令并不总是接受等号后面的所有字符串。例如:set one=1 & echo Hiya。关于括号的提醒很好,它们确实非常有用。 - Brent Rittenhouse

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