批处理之 正确使用for语句 以及!errorlevel!、%errorlevel% 与 DelayedExpansion用法详解

13 篇文章 0 订阅
    昨天在使用批处理中的 for 语句的时候,最初我采用下面这种写法:
@echo off
set ip=192.168.1
for /l %%i in (1,1,5) do (
    set ip=%ip%.%%i    :: 遍历 IP 池
    echo ip=%ip%  i=%%i
)

图1
    运行结果如上图,显示变量 ip 的值始终为 192.168.1,并没有按预期递增输出 IP。

    经过查阅资料,我找到了原因:
    1、 批处理是解释型语言,脚本不会被编译。在运行时,脚本中所引用的 变量会被简单替换成对应的文本(在批处理中称为 变量扩展,Expansion),这一点可以用 C语言中的宏来理解。
    2、批处理中对于变量的赋值(将变量进行扩展) 默认发生在第一次读取到一条完整的命令之后,注意, 命令仅仅只是被读取还没有被执行

    明白了这 2 点,上面脚本运行的错误也就解释得通了。
    对于 for 语句而言,一条完整命令的形式是 for /arg %%var in (SET) do (COMMAND) 这样的, 包括了 do 之后括号里的所有命令,所以他们只会被读取而不会被执行,自然变量 ip 也就不会被赋值了。在上文脚本中,命令 for /l %%i in (1,1,5) do (set ip=%ip%.%%i ...) 第一次被系统完整读取到时,变量 ip 的值为 192.168.1,所以变量 ip 的打印结果一直是 192.168.1
    幸好,微软的工程师在开发解释器时已经发现了这一点,并为我们提供了 setlocal 命令用于 改变解释器的规则

    将上文脚本更改成下面的写法:
@echo off
setlocal EnableDelayedExpansion
set ip=192.168.1
for /l %%i in (1,1,5) do (
    set ip=%ip%.%%i
    echo ip=!ip!  i=%%i
)
:: 写成 enabledelayedexpansion 也是可以的,不区分大小写
:: 必须使用英文感叹号 ! 而不是百分号来引用需要延时扩展的变量,!ip!

图2
    这次的运行结果从上图可以看到,输出和计划一致。

    使用 setlocal EnableDelayedExpansion 命令后,可以让解释器在每次循环的执行过程中都对变量 ip 进行一次赋值。这种 循环体中为变量多次赋值的操作在批处理中 叫做 对变量进行延时扩展(Delayed Expansion)
    再来看 2 个例子,搞清楚使用感叹号 ! 和百分号 % 的区别:
【例 1】
@echo off
setlocal enabledelayedexpansion
echo 开始搜索文件,请等待程序提示“搜索完成”再退出 ...
echo.
for /r /d %%i in (.) do (
    dir %%i *.xls* 2>nul | find /i "xls"
    if %errorlevel% equ 0 (    :: 此处使用百分号 %
        echo  文件位置 %%i
    )
)
echo.
echo 搜索完成!回车可退出。
pause >nul

图3

【例 2】
@echo off
setlocal enabledelayedexpansion
echo 开始搜索文件,请等待程序提示“搜索完成”再退出 ...
echo.
for /r /d %%i in (.) do (
    dir %%i *.xls* 2>nul | find /i "xls"
    if !errorlevel! equ 0 (    :: 此处使用感叹号 !
        echo  文件位置 %%i
    )
)
echo.
echo 搜索完成!回车可退出。
pause >nul

图4
    执行结果的对比很明显。 使用百分号 % 时,if 条件判断语句中的 errorlevel 值表示第一次读取完整 for 命令时的值,也就是执行完 echo. 命令后的 errorlevel(有点绕,不着急,好好想想)。命令 echo. 执行成功,所以 errorlevel 一直都是 0,这导致输出结果中打印了很多无用的信息。 使用感叹号 ! 时,if 条件判断语句中的 errorlevel 值是 for 循环中每次执行完 find 命令后的 errorlevel 值,这才是我们计划中要用的。
    有关 延时扩展变量 的用法,不知道现在你懂了没有?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值