预期input:开始= 1,结束= 500,间隔= 100
预期产出:
1,100
101,200
201,300
301,400
401,500
@echo off set start=1 set end=500 set interval=100 for /L %%g in (%start%, %interval%, %end%) do ( set first=%%g set /a last=%first% -1 + %interval% echo %first% , %last% )
实际产出:
401,401 -1 + 100
401,401 -1 + 100
401,401 -1 + 100
401,401 -1 + 100
401,401 -1 + 100
不知道为什么第一次分配401值,欣赏任何帮助
这是一个经典的延迟扩展问题。 键入help set或set /? 从命令提示符下进行关于延迟扩展的讨论(稍微完成一半的帮助)。
正常扩展使用%var%发生在行被parsing时。 问题是你的整个FOR循环块被一次parsing。 所以你看到了循环开始之前存在的常量值。 401的价值可能是从以前的运行。
解决scheme是延迟扩展。 首先,您必须使用setlocal enableDelayedExpansion启用它。 那你用!var! 而不是%var% 。 这将在执行时间而不是在parsing时间给出值。
另外,使用set /a时不需要扩展数字variables。
@echo off setlocal enableDelayedExpansion set start=1 set end=500 set interval=100 for /L %%g in (%start%, %interval%, %end%) do ( set /a first=%%g, last=first-1+interval echo !first!, !last! )
@dbenham是对的。 我会抛出一个select。 我发现延迟扩展对于更长的子程序来说有点丑陋和混乱,所以我倾向于将唯一的call作为for循环的“主体”。 在callvariables扩展内部发生“正常”。 注意:
@echo off setlocal set start=1 set end=500 set interval=100 for /L %%g in (%start%, %interval%, %end%) do call :_d %%g endlocal goto :EOF :_d set /a last=%1 - 1 + interval echo %1, %last%
对于这个特殊情况,可以肯定的是更多的代码,但是对于不太重要的batch file,我认为这是一个“胜利”。
setlocal :你没有setlocal / endlocal ,所以first和last值将会持续执行,假设你继续在同一个shell中运行它们,并在第二次运行你的代码时给你不同的结果。 我倾向于将我的batch file包装在一个setlocal / endlocal对中,以防止脚本中使用的variables“泄漏”到父shell的环境中。
最后,我会回应@VasiliSyrakis所说的:如果你可以避免使用cmd.exe那么一定要避免它。 我倾向于批量写很多东西,但是,不可否认,这有点像使用螺丝刀敲钉子的问题。