在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
一,什么是延迟环境变量扩展? 延迟变量全称"延迟环境变量扩展",要理解这个东西,我们还得先理解一下什么叫变量扩展! 然后CMD就会找到变量名对应的值,用该值替换掉这个变量名字(name),(如果变量名不存在值,就返回空值).再将这 例1, @echo off set var=test echo %var% pause CMD在读取到echo %var%这句命令后,就会进行匹配操作,它马上就发现var字符两边有%号,这时CMD就会把它当作一 什么是环境变量扩展知道了,那什么是延迟环境变量扩展呢? 在理解环境变量扩展时,我们知道CMD在解释命令时,首先会把一条完整的命令进行读取,然后进行匹配操作,匹配时 例2, @echo off for /l %%i in (1,1,5) do ( set var=%%i echo %var% ) pause 执行后会显示5个空行的错误提示!为什么?根据我们上面说的知识来理解。 通过这两个例子,大家应该已经理解,如果只有环境变量扩展这个过程的话,如果我们在可以嵌套命令的命令中执行 在批处理中,我们可以用setloacl enabledelayedexpansion 这个命令来启用"延迟环境变量扩展" ,在我们启用 例3, @echo off setlocal enabledelayedexpansion set var=1 for /l %%i in (1,1,5) do ( set /a var =%%i echo !var! ) pause 这样大家应该明白什么是延迟环境变量扩展了吧.再来一个例子 例4, @echo off set var=test & echo %test% pause 这条命令放在一行,表示他是一条完整的命令,不启用"延迟环境变量扩展",就会出现上面的赋值错误!改成下这样就 @echo off setlocal enabledelayedexpansion set var=test & echo !var! pause 二,批处理变量延迟详解 关于环境变量延迟扩展,使用set /?可以查看到部分说明,不过考虑到其粗劣的翻译水平,建议在查看之前,首 在许多可见的官方文档中,均将使用一对百分号闭合环境变量以完成对其值的替换行为称之为“扩展(expansion 而命令解释器是扩展环境变量的行为大致如下:首先读取命令行的一条完整语句,在进行一些先期的预处理之后 而一条“完整的语句”,在NT的命令解释器CMD中被解释为“for if else”等含有语句块的语句和用“& | && || 而为了能够在for语句内部感知环境变量的动态变化,CMD设计了延迟的环境变量扩展特性,也就是说,当CMD读取 延迟环境变量扩展特性在CMD中缺省是关闭的,开启它的方法目前有两个:一是CMD /v:off(此处说法有误,应为
本例启用了变量延迟,是个正确的例子! 例1, @echo off & setlocal EnableDelayedExpansion for /f "tokens=* delims=" %%i in ("Hello world.") do ( set n=%%i set n=!n:ld.=t! set n=!n:o w= S! set n=!n:He=Wi! echo !n! ) Pause 将上面代码保存为.bat双击执行后会显示“Will Sort”字符串,下面将讲解每个语句的意思:
需要注意的是,一旦启用了变量延迟,就要用!号把变量括起来,而不能用%号。 好了,每句的意思已经说完了,下面要讲本帖真正要讨论的变量延迟的问题。 而为了能够在for语句内部感知环境变量的动态变化,CMD设计了延迟的环境变量扩展特性,也就是说,当CMD读取 总的来说是,在没有启用变量延迟的情况下,凡是在括号内(即do里面)的变量,在执行for语句之前,就已经被 例2, @echo off for /f "tokens=* delims=" %%i in ("Hello world.") do ( set n=%%i set n=%n:ld.=t% set n=%n:o w= S% set n=%n:He=Wi% echo %n% ) Pause 这和前面的例子差不多,只是所有!号都换成%号,这是个错误的例子。因为它没有启用变量延迟,也没有使用! 则是说在本例中的以下几句 set n=%%i set n=%n:ld.=t% set n=%n:o w= S% set n=%n:He=Wi% echo %n% 第一句能正常执行并达到它的目的,因为它只是单纯地将%%i的值赋予给变量n,所以没有任何问题。其它几句属 所以,最后echo %n%的时候变量n还是个空值,而echo命令没有东西可以显示,就只有显示“ECHO 处于关闭状态 通过这个例子的说明,相信大家已经知道变量延迟的作用吧!我们再回头来看看例1。 启用变量延迟后,在执行 set n=!n:ld.=t! set n=!n:o w= S! set n=!n:He=Wi! echo !n! 这些语句前,它们里面的变量n不会马上被CMD替换(启用延迟后,CMD变得有耐性啦^_^),而未被替换的话,那么n 不要以为只有for才要用变量延迟,下面这个例子同样需要 例3,这是个错误的例子 @echo off set mm=girl&echo %mm% pause 执行后依然显示“ECHO 处于关闭状态”。 原因是没有启用延迟,而且在set mm=girl&echo %mm%语句前没有其它命令对mm进行赋值。这时当CMD执行set 有人会问,echo前面不是给mm赋值了吗? 总的来说是,如果不启用变量延迟,在本例中,echo是不会理会也不会知道,它前面(指同一行语句)是否有其 大家这样做就明白了: @echo off set mm=boy set mm=girl&echo %mm% pause 看看显示什么结果就知道了! 这样编写例3才正确: @echo off&setlocal EnableDelayedExpansion set mm=girl&echo !mm! pause 开启了变量延迟,变量扩展(替换)的行为就推迟到echo命令执行时,这时echo能感知它前面的命令(本例的set) 三,批处理延迟变量(通俗解释) 变量延迟 setlocal EnableDelayedExpansion 但可能就是因为专业,所以才看不懂,因为学cmd批处理的并不一定都是学计算机专业的。这个鬼东西确实不太好 言归正传 要想了解延迟变量,首先你要明白什么是“复合语句”好像又来了个“专业”名词,别急,这个超好理解。所谓 for /f "delims=" %%i in (a.txt) do ( set var=%%i echo %%i set num=%%i ) 这里do后面的三句命令,在一对()里面,这就叫“复合语句”,当然不止for 还有if 等等。。。 if "%var%"=="abc" ( echo ok set lis=123 ) 反正就是凡是()里的所有命令,就叫“复合语句” 好,了解了复合语句,现在开始讲延迟变量,也就说,在复合语句中才要使用延迟变量。 我们只要知道在什么时候需要使用延迟变量,如何才能正确提取到我们需要的变量就可以了,这才是我们的目的。 例1, @echo off for /l %%i in (1 1 10) do ( set var=%%i echo %var% ) Pause 运行上面的代码,显示什么?显示10个echo处于关闭状态。按照逻辑,var的值应该依次是 1、2、3........10 才 这就是因为没有开启 延迟变量 的缘故,cmd把var的值当作复合语句之前的值来引用, 例2, @echo off set var=abc for /l %%i in (1 1 10) do ( set var=%%i echo %var% ) Pause 运行上面的代码,会显示什么,大家应该知道了吧? 例3, @echo off set var=abc for /l %%i in (1 1 5) do ( set var%%i=%%i echo %var% ) echo %var1% %var2% %var3% %var4% %var5% pause 运行上面的代码后,复合语句中所赋的值全部显示出来了,这说明什么呢? 说明,在复合语句中,并不是没有给变量赋值,只是你若没有开启延迟变量,你就没法在复合语句中提取到它,要 变量的表示方法:两种: 1、%var% 2、!var! 例4, @echo off setlocal EnableDelayedExpansion set var=abc for /l %%i in (1 1 10) do ( set var=%%i echo %var% echo !var! ) Pause 注意:例子中有两个echo 一个是显示 %var% 一个是显示 !var! 例5, @echo off setlocal EnableDelayedExpansion for /l %%i in (1 1 5) do ( set var%%i=%%i ) echo %var1% %var2% %var3% %var4% %var5% echo !var1! !var2! !var3! !var4! !var5! pause 这个例子说明什么,不用再解释了吧?
什么时候使用延迟变量?如何使用?这些一直是使新手困惑的地方,那到底是怎么样的呢?那请看下面的例子, 例1, @echo off set /a num=0 for /l %%i in (1 1 3) do ( Rem ================================ set /a num =1 Rem 原意是变量num的值每次都加1 Rem ================================ echo %num% ) pause>nul 先猜猜看,运行之后的结果是什么呢?你是不是认为它会显示:1 2 3 呢?我想大部分人会这么认为。你再将以 原来这个是因为,批处理在处理for 或者if 语句中的变量时,先要进行预处理,把其中的用%%括起来的变量,先 例2, @echo off Rem ''''///////下面先申明起用延迟变量///////////// setlocal enabledelayedexpansion set /a num=0 for /l %%i in (1 1 3) do ( Rem ================================ set /a num =1 Rem 变量num的值每次都加1 Rem ================================ Rem '''''''//////////////////下面的变量不能再用"%"括起来,而应该用"!"//////////// echo !num! ) pause>nul
2、什么时候用延迟变量? 3、怎么用延迟变量? 4、其实在使用变量嵌套变量也可以使用变量延迟的。 例3, @echo off set a=1 set b1=10 echo %b%a%% pause 执行显示,得到 %b1% 其实我想得到的是 赋予b1的值,即 10 那么如何实现呢?将上例修改如下, 例4, @echo off set a=1&set b1=10 call,echo %%b%a%%% pause>nul call 这里实际是对命令行进行重新组织扩展,先扩展%%b%a%%%里面的%a%,使%a%变成a的值1,再用cal来扩展%b1% 也可以用变量延迟来实现,方法如下: 例5, @echo off set /a a=1,b1=10 Setlocal EnableDelayedExpansion echo:!b%a%! ... pause
@echo off&setlocal enabledelayedexpansion set a=1000 set b=dd set a%b%=9000 set c=!a%b%! echo %c% pause 执行一下,看看显示的将是什么?为什么是这样?相信通过例4,例5你也能分析得出来吧? |
请发表评论