Windows 批处理(BAT文件)循环中变量的值不变问题

问题:

在Windows批处理中,试图在循环中打印一个计算变量,但结果却是该变量的值总是不变:

@echo off
title timeout 函数测试
@echo 定时开始 ......
set k =0
for /L %%i in (1,1,10) do (
    timeout /T 5 > nul
    @echo %%i
    set /a k = %%i * 5 
    echo %k% 秒过去了
)

@echo 定时结束。

上面这段代码的含义是,定时5秒循环10次,每次定时结束,打印“多少秒过去了”。但结果却是这样的:

D:\test\BAT>timeout-test.bat
定时开始 ......
1
50 秒过去了
2
50 秒过去了
3
50 秒过去了
4
50 秒过去了
5
50 秒过去了
6
50 秒过去了
7
50 秒过去了
8
50 秒过去了
9
50 秒过去了
10
50 秒过去了
定时结束。

可见,变量k的值并没有随着循环变量i的值变化而变化。

解决:

        该问题和Windows批处理脚本的处理模式有关,我的理解是:批处理是读一行解释、执行一行,解释完后(变量的替换等),就不再解释了,就是说即便外部程序在逻辑上又改变了变量的值,但解释器已经不再理会了。

解决方法就是使用延迟变量解释,告诉解释器这是一个变量,后面的值还会改变。

使用延迟变量条件:

(1)打开延迟扩展设置: setlocal enabledelayedexpansion

(2)使用!k!(2个感叹号夹1个变量)来读取变量,不开启延迟扩展时,读取方式是 %k%(2个百分号夹1个变量)

改进后的代码:

@echo off
setlocal enabledelayedexpansion
title timeout 函数测试
@echo 定时开始 ......
set k =0
for /L %%i in (1,1,10) do (
	timeout /T 5 > nul
    @echo %%i
    set /a k = %%i * 5 
	@echo !k! 秒过去了	
)

@echo 定时结束。

改进后的效果:

D:\test\BAT>timeout-test.bat
定时开始 ......
1
5 秒过去了
2
10 秒过去了
3
15 秒过去了
4
20 秒过去了
5
25 秒过去了
6
30 秒过去了
7
35 秒过去了
8
40 秒过去了
9
45 秒过去了
10
50 秒过去了
定时结束。

可见,改进后的程序能够按照预期目标完整地输出定时信息。

说明:

1、批处理中,数学计算表达式的写法:set /a  [表达式]

2、不显示命令行本身: @命令行

参考:

1、批处理中setlocal enabledelayedexpansion的作用详细整理,https://www.jb51.net/article/29323.htm

posted @ 2020-07-15 10:12  hongweigg  阅读(167)  评论(0编辑  收藏  举报