位置: 编程技术 - 正文

dos 环境变量延迟扩展enabledelayedexpansion详解(环境变量windows)

编辑:rootadmin

推荐整理分享dos 环境变量延迟扩展enabledelayedexpansion详解(环境变量windows),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:window环境变量生效,环境变量xdg_runtime_dir,环境变量xdg_runtime_dir,环境变量display,dosbox环境变量,dos 添加环境变量,dos环境变量路径设置,dos 添加环境变量,内容如对您有帮助,希望把文章链接给更多的朋友!

一,什么是延迟环境变量扩展?

延迟变量全称"延迟环境变量扩展",要理解这个东西,我们还得先理解一下什么叫变量扩展! CMD在解释我们的命令的时候,首先会读取一条完整的命令,然后对其进行一些命令格式的匹配操作,看你所输入的命令格式是不是符合它的要求.如果我们要在命令中引用一些变量,那么我们如何让CMD在解释我们的命令时,能识别出这个变量呢&#;这时我们就可以在变量名字两边加一个%号,如%name%.当CMD在读取我们的整条命令进行格式匹配的时候,就会发现name这个字符两边加了%号,就不会把它当作普通字符处理,而是会把它当作一个变量处理,变量名叫name

然后CMD就会找到变量名对应的值,用该值替换掉这个变量名字(name),(如果变量名不存在值,就返回空值).再将这个替换好并且匹配的命令执行!这个替换值的过程,就叫做变量扩展,说白了就是把变量的名字,用它的值给替换掉后执行!也就是批处理如何识别一个变量的过程.(注意:这里只是变量的扩展的意思,不是延迟环境变量扩展,要理解延迟环境变量扩展,必须先理解什么是变量的扩展) 也就是批处理如何识别一个变量的过程.

例1,

CMD在读取到echo %var%这句命令后,就会进行匹配操作,它马上就发现var字符两边有%号,这时CMD就会把它当作一个变量处理,查看这个var变量名是不是有值,如果有就用该值把变量名var给替换掉,这里我们的var在上一条命令set var=test中,给var赋值为test,所以CMD会用test把%var%这个变量名替换掉,替换后的结果就为echo test了.这些步骤都是CMD进行匹配操作的步骤,匹配完后,他再执行echo test这条语句,这时我们的CMD中就会echo出一个test了.

什么是环境变量扩展知道了,那什么是延迟环境变量扩展呢&#;

在理解环境变量扩展时,我们知道CMD在解释命令时,首先会把一条完整的命令进行读取,然后进行匹配操作,匹配时它会把命令里的变量用变量的值给替换掉,然后执行这个替换好的命令.问题就出在"一条完整的命令",在BAT中,IF FOR这样的命令都可以加括号,将一些命令嵌套在里面执行.这样的话对于一条可以加扩号嵌其他命令的命令,他的完整格式就是for %%i in (....)这样一个整体.此时,如果我们如果在括号里面嵌入一些设置变量值的命令,就会出现问题了!

例2,

执行后会显示5个空行的错误提示!为什么&#;根据我们上面说的知识来理解。

通过这两个例子,大家应该已经理解,如果只有环境变量扩展这个过程的话,如果我们在可以嵌套命令的命令中执行赋值操作时,会让我们的BAT出现给变量赋值的问题.那么这个时候"延迟环境变量扩展",这个概念就被提出来了。

在批处理中,我们可以用setloacl enabledelayedexpansion 这个命令来启用"延迟环境变量扩展" ,在我们启用了"延迟环境变量扩展"后,当CMD在解释含有嵌套格式的命令时,他会把嵌套的命令一条一条的先执行一次,然后再进行匹配操作,这样我们的赋值操作就会完成.并且在"延迟环境变量扩展"启用后,CMD会用!号来判断这是不是一个变量。如没启用前变量用%name%这样的格式判断,启用后就用!name!这样的格式判断了,这个符号我们需要注意!

例3,

这样大家应该明白什么是延迟环境变量扩展了吧.再来一个例子

例4,

这条命令放在一行,表示他是一条完整的命令,不启用"延迟环境变量扩展",就会出现上面的赋值错误!改成下这样就OK了:

二,批处理变量延迟详解

关于环境变量延迟扩展,使用set /&#;可以查看到部分说明,不过考虑到其粗劣的翻译水平,建议在查看之前,首先chcp 切换为英文查看原英文说明。鉴于文中已说得十分详尽,而且有数个代码示例,应该不难理解。在此仅略作一些补充。

在许多可见的官方文档中,均将使用一对百分号闭合环境变量以完成对其值的替换行为称之为“扩展(expansion)”,这其实是一个第一方的概念,是从命令解释器的角度进行称谓的,而从我们使用者的角度来看,则可以将它看作是引用(Reference)、调用(Call)或者获取(Get)。

而命令解释器是扩展环境变量的行为大致如下:首先读取命令行的一条完整语句,在进行一些先期的预处理之后,命令被解释执行之前,会对其中用百分号闭合的字符串进行匹配,如果在环境空间中找到了与字符串相匹配的环境变量,则用其值替换掉原字符串及百分号本身,如果未得到匹配,则用一个空串替换,这个过程就是环境变量的“扩展”,它仍然属于命令行的预处理范畴。

而一条“完整的语句”,在NT的命令解释器CMD中被解释为“for if else”等含有语句块的语句和用“& | && ||”等连接起来的复合语句。 因此,当CMD读取for语句时,其后用一对圆扩号闭合的所有语句将一同读取,并完成必要的预处理工作,这其中就包括环境变量的扩展,所以在for中的所有语句执行之前,所有的环境变量都已经被替换为for之前所设定的值,从而成为一个字符串常量,而不再是变量。无论在for中将那些环境变量如何修改,真正受到影响的只是环境变量空间,而非for语句内部。

而为了能够在for语句内部感知环境变量的动态变化,CMD设计了延迟的环境变量扩展特性,也就是说,当CMD读取了一条完整的语句之后,它不会立即执行变量的扩展行为,而会在某个单条语句执行之前再进行扩展,也就是说,这个扩展行为被“延迟”了。

延迟环境变量扩展特性在CMD中缺省是关闭的,开启它的方法目前有两个:一是CMD /v:off(此处说法有误,应为 CMD /v:on——namejm 注),它会打开一个新的命令行外壳,在使用exit退出这个外壳之前,扩展特性始终有效,常用于命令行环境中;二是setlocal EnableDelayedExpansion,它会使环境变量的修改限制到局部空间中,在endlocal之后,扩展特性和之前对环境变量的修改将一同消失,常用于批处理语句中。

上面是willsort写的帖子对于新手来说比较难理解。不过没关系,我们先分析一个例子,同样是引用willsort老大的。

本例启用了变量延迟,是个正确的例子!

例1,

将上面代码保存为.bat双击执行后会显示“Will Sort”字符串,下面将讲解每个语句的意思:

1.@echo off & setlocal EnableDelayedExpansion关闭命令回显,并启用变量延迟

2.for /f "tokens=* delims=" %%i in ("Hello world.") do ( )for命令及其参数的使用,请大家在论坛里搜索相关字眼。限于篇幅问题,这里不作讨论。如果此时你不明白它的意思,那么你就当它的作用是把字符串“Hello world.”赋值给%%i好了,当然这只是权宜之计,以后一定要学习for的使用!

3.set n=%%i把%%i的值(即Hello world.)赋予给变量n,这个大家都知道吧

4.set n=!n:ld.=t!这里要讲讲set替换字符的功能了。这个语句的意思是,先获取变量n的值(此时n的值是“Hello world.”),然后将字符“t”替换字符“ld.”,然后再将替换后的结果再次赋值给变量n(此时n的值变为“Hello wort”)。至于set替换字符的编写格式,大家可以在CMD键入“set/&#;”找到“%PATH:str1=str2%”这段有说明

5.set n=!n:o w= S!意思和上句一样,只是替换和被替换的内容不同。它是将“ S”替换“o w”(注意S前面和w前面都有个空格),其实willsort老大是想证明set替换字符是支持句点和空格的(第4句“ld”后面有个.)。此时n的值为“Hell Sort”

6.set n=!n:He=Wi!这句不用说了吧,执行完这句后n的值为“Will Sort”

7.echo !n!显示变量n的值

需要注意的是,一旦启用了变量延迟,就要用!号把变量括起来,而不能用%号。

好了,每句的意思已经说完了,下面要讲本帖真正要讨论的变量延迟的问题。这里又要引用Will Sort老大的说明:当CMD读取for语句时,其后用一对圆括号闭合的所有语句将一同读取,并完成必要的预处理工作,这其中就包括环境变量的扩展,所以在for中的所有语句执行之前,所有的环境变量都已经被替换为for之前所设定的值,从而成为一个字符串常量,而不再是变量。

而为了能够在for语句内部感知环境变量的动态变化,CMD设计了延迟的环境变量扩展特性,也就是说,当CMD读取了一条完整的语句之后,它不会立即执行变量的扩展行为,而会在某个单条语句执行之前再进行扩展,也就是说,这个扩展行为被“延迟”了。

总的来说是,在没有启用变量延迟的情况下,凡是在括号内(即do里面)的变量,在执行for语句之前,就已经被替换成for语句之前其它命令对该变量所赋予的值。这句话不懂没关系,下面再看一个例子,看完你就会明白。

例2,

这和前面的例子差不多,只是所有!号都换成%号,这是个错误的例子。因为它没有启用变量延迟,也没有使用!号把变量括起来。我们看到它的执行结果是显示“ECHO 处于关闭状态”。为什么会这样呢?原因是,在没有启用变量延迟的情况下,凡是在括号内(即do里面)的变量,在执行for语句之前,就已经被替换成for语句之前其它命令对该变量所赋予的值。

则是说在本例中的以下几句

第一句能正常执行并达到它的目的,因为它只是单纯地将%%i的值赋予给变量n,所以没有任何问题。其它几句属这样情况:早在for语句执行前,CMD就急不切待地将这几句里面的所有变量n一同执行替换行为,替换为for之前,其它命令对n所设置的值,从而使n变成一个常量。但在本例中,for语句之前只有@echo off这句,并没有其它命令对n作过任何赋值行为,所以在for之前,变量n的值为空值。 即是说,set n=%n:ld.=t% 这句里面的变量n,在CMD读取(注意是读取不是执行)完整个for语句后(这时还未轮到set执行自己的任务),就立刻被替换为一个空值,一个空值里面没有任何东西,所以就不存在一字符替换另一字符这种说法(没有东西怎么替换?)。最终到执行set n=%n:ld.=t%语句时,它只是获取一个空值,再给变量n赋予空值而已。其它几句也是一样原理。

所以,最后echo %n%的时候变量n还是个空值,而echo命令没有东西可以显示,就只有显示“ECHO 处于关闭状态”这句来说明自己的状态

通过这个例子的说明,相信大家已经知道变量延迟的作用吧!我们再回头来看看例1。

启用变量延迟后,在执行

这些语句前,它们里面的变量n不会马上被CMD替换(启用延迟后,CMD变得有耐性啦^_^),而未被替换的话,那么n就还是变量,而不是常量。等到执行set n=!n:ld.=t!等这几句时,变量n才被替换。这样每个set命令都能感知变量n的任何变化,从而作出正确的替换行为。这就是变量延迟啦!

不要以为只有for才要用变量延迟,下面这个例子同样需要

例3,这是个错误的例子

执行后依然显示“ECHO 处于关闭状态”。

dos 环境变量延迟扩展enabledelayedexpansion详解(环境变量windows)

原因是没有启用延迟,而且在set mm=girl&echo %mm%语句前没有其它命令对mm进行赋值。这时当CMD执行set mm=girl&echo %mm%语句前,就已经急不切待地把变量mm的值替换了,而又因为前面没给mm赋值,所以mm被替换为空值,变成常量。等到echo命令执行时,它其实是echo一个不会变化的常量,本例中即是空值。

有人会问,echo前面不是给mm赋值了吗?这个就要关系到CMD解释命令的步骤,大家可以参详本帖开头willsort的帖子。

总的来说是,如果不启用变量延迟,在本例中,echo是不会理会也不会知道,它前面(指同一行语句)是否有其它命令给mm赋值。它只会从set mm=girl&echo %mm%这句以上的语句中获取它所要显示的变量的内容,也就是说,上一行或上几行的命令将mm设置成什么值,echo命令就显示什么值。

大家这样做就明白了:

看看显示什么结果就知道了!

这样编写例3才正确:

开启了变量延迟,变量扩展(替换)的行为就推迟到echo命令执行时,这时echo能感知它前面的命令(本例的set)对变量mm做了什么“坏事”,从而作出正确的判断并执行

三,批处理延迟变量(通俗解释)

变量延迟 setlocal EnableDelayedExpansion 一个让大多数新手头痛的问题,网上教程虽多,但多半都是看不懂的,里面的专业术语太多。以 cn-dos 联盟的willsort的这篇教程为例,(个人认为是解释的极具权威和专业的)

但可能就是因为专业,所以才看不懂,因为学cmd批处理的并不一定都是学计算机专业的。这个鬼东西确实不太好理解,在下也是摸爬滚打多时,总结出一点点经验,现用通俗的方法解释出来,希望能给新手些帮助,老鸟们见笑了,若有不对的地方,欢迎指出。

言归正传在什么时候需要延迟变量,和该如何引用延迟变量,我想这才是大多数新手迫切想要知道的问题。耐心看完下面的内容,我想对你应该是有帮助的。

要想了解延迟变量,首先你要明白什么是“复合语句”好像又来了个“专业”名词,别急,这个超好理解。所谓“复合语句”就是指一对()里的所有命令。比如for的do后面如:

这里do后面的三句命令,在一对()里面,这就叫“复合语句”,当然不止for 还有if 等等。。。如:

反正就是凡是()里的所有命令,就叫“复合语句”另外:这也是复合语句 set abc=&echo %abc% 没错,通过管道命令&连接起来的命令,也是复合语句。

好,了解了复合语句,现在开始讲延迟变量,也就说,在复合语句中才要使用延迟变量。我们先不去理解什么叫“变量的扩展”这玩意叫法太专业,我到现在都不太明白,

我们只要知道在什么时候需要使用延迟变量,如何才能正确提取到我们需要的变量就可以了,这才是我们的目的。cmd在处理“复合语句”的时候,如果“复合语句”中用到了变量,会把变量的值当作复合语句之前变量的值来引用。如果在此之前变量没有被赋值,就把它当成空值。

例1,

运行上面的代码,显示什么?显示个echo处于关闭状态。按照逻辑,var的值应该依次是 1、2、3........ 才对啊!

这就是因为没有开启 延迟变量 的缘故,cmd把var的值当作复合语句之前的值来引用,而在本例中,复合语句之前并没有给var定义,所以var的值是空的,所以会显示个echo处于关闭状态。

例2,

运行上面的代码,会显示什么,大家应该知道了吧?

例3,

运行上面的代码后,复合语句中所赋的值全部显示出来了,这说明什么呢?

说明,在复合语句中,并不是没有给变量赋值,只是你若没有开启延迟变量,你就没法在复合语句中提取到它,要等复合语句运行完毕后,才能提取到。

变量的表示方法:两种: 1、%var% 2、!var!第一种表示方法,大家都知道,第二种就是引用 延迟的变量。在开启了延迟变量的情况下,如果在复合语句之外,用哪种方法表示都可以。但是你若要在复合语句中引用复合语句即时得到的变量,就要用第二种方法。看例子

例4,

注意:例子中有两个echo 一个是显示 %var% 一个是显示 !var!结果很明白了,%var% 显示的结果是复合语句之前变量var的值,而 !var! 显示的就是复合语句中即时得到的值。

例5,

这个例子说明什么,不用再解释了吧?说明在开启了延迟变量的情况下,且在复合语句之外,用两种方法都可以表示变量。就说到这吧。以上的解释,完全是出于个人的理解,也是为方便非专业人士理解,解释肯定有错误的地方、就象学习英语时,为方便记忆,用汉字的读音来作解释一样。呵呵,是一种“偏门”各位新手千万不要把以上所说的当成是“真理”,否则就变成是“误人”了。

四,什么时候使用延迟变量?如何使用?

什么时候使用延迟变量?如何使用?这些一直是使新手困惑的地方,那到底是怎么样的呢?那请看下面的例子,我们将一步步引导大家。

例1,

先猜猜看,运行之后的结果是什么呢?你是不是认为它会显示:1 2 3 呢?我想大部分人会这么认为。你再将以上代码保存为批处理文件,运行,看看结果。你会看到,显示的结果并不是意料中的 1 2 3 而是 0 0 0,这个是为什么呢?

原来这个是因为,批处理在处理for 或者if 语句中的变量时,先要进行预处理,把其中的用%%括起来的变量,先替换为语句之前的变量(如上面的代码,for语句中的%num%早就被替换为语句前的 值:0),所以,for语句运行时,虽然已经给变量加了1,但是,值却不变(因为echo %num%中的%num%早已被替换为:0了)。那么,要实现(for或者if)语句中的变量实时的变化(如这里,我就要将1 2 3 显示出来)要怎么办呢?那就要起用延迟变量,先在批处理中申明:setlocal enabledelayedexpansion 然后,将语句:echo %num%改成!num!(也就是将“%”改成“!”),这样就可以达到效果了,演示代码:

例2,

归纳总结:1、为什么要用延迟变量?让if语句和for语句中的变量实时变化;

2、什么时候用延迟变量?一般是用在 for 语句和 if 语句中;

3、怎么用延迟变量?先在批处理中申明起用延迟变量:setlocal enabledelayedexpansion然后将 for 语句、if语句中的变量用两个"!"括起来即可

4、其实在使用变量嵌套变量也可以使用变量延迟的。

例3,

执行显示,得到 %b1%

其实我想得到的是 赋予b1的值,即 那么如何实现呢&#;将上例修改如下,

例4,

call 这里实际是对命令行进行重新组织扩展,先扩展%%b%a%%%里面的%a%,使%a%变成a的值1,再用cal来扩展%b1%。

也可以用变量延迟来实现,方法如下:

例5,

call 在这里的用法实际是变量延迟的一种快捷方式,变量延迟一般用在for的循环体里面。call,%%b%a%%% 这里的逗号实际是一个分隔符,和空格一样,还有很多分隔符可用,比如上例中的 echo:!b%a%! ,当然并不是所有的命令都可以这样用,看情况而定……

例6,

执行一下,看看显示的将是什么?为什么是这样?相信通过例4,例5你也能分析得出来吧?

bat命令入门与高级技巧详解 目录第一章批处理基础第一节常用批处理内部命令简介1、REM和::2、ECHO和@3、PAUSE4、ERRORLEVEL5、TITLE6、COLOR7、mode配置系统设备8、GOTO和:9、FIND、START、as

bat如何延时删除指定文件夹中的文件 本文介绍的是bat如何延时删除指定文件夹中的文件,下面话不多说了,有需要的来一起看看下面的详细内容。一、bat延时xp程序中通过ping.0.0.1-n来实

DOS批处理中%~dp0等扩充变量语法详解 有时候我们看到别人使用%~dp0~是扩展的意思,相当于把一个相对路径转换绝对路径%0代指批处理文件自身%1表示批处理文件命令行接收到的第一个参数,%

标签: 环境变量windows

本文链接地址:https://www.jiuchutong.com/biancheng/371618.html 转载请保留说明!

上一篇:批处理常用网络命令和符号篇(常用的批处理文件)

下一篇:bat命令入门与高级技巧详解(bat命令详解)

  • 税控盘抄报逾期怎么办
  • 广东通用机打发票可以抵扣吗
  • 税务ukey使用教程视频
  • 存货盘盈如何处理
  • 药店的主营业务有哪些
  • 退货开具红字发票销项税为负数税务局会查吗
  • 小规模纳税人的增值税账务处理
  • 库存商品的进销存怎么做账
  • 取得的管理部门证书
  • 私营独资企业可以变更法人吗
  • 工业企业电费出售会计分录怎么写?
  • 3%税率是一般纳税人还是小规模
  • 营业账簿印花税包括什么
  • 一般纳税人哪些项目可以简易征收
  • 怎样算纳税人
  • 广告费发票收到但是不抵扣怎么做账?
  • 购货方预付货款的分录
  • 个人出租房屋交税如何计算
  • 当月未抵扣进项税在进项税额明细表怎么填
  • 外账的银行存款怎么处理
  • 报废的周转物怎么处理?
  • 专用发票可以抵税是什么意思
  • 增值税发票是不是可以抵税
  • 职工福利费支付范围
  • 固定资产可以一次性抵扣进项税吗
  • 提供建筑安装服务
  • 企业信用贷款账户是什么
  • 领用材料已抵扣进项税
  • 代垫运费增值税怎么算
  • cvpr2020结果
  • php异步请求方式
  • 企业合并发生的审计费用,评估费用会计分录
  • 基建费用如何摊销
  • php加减
  • 代垫运费算收入吗
  • 为什么我们认为北京人已经学会使用火
  • 【机器学习面试总结】————(一)
  • 横看成横看成岭侧成峰的下一句
  • 完美解决win10间歇性掉线
  • 非公党建党费收缴
  • 财务费用包括什么利息
  • 确认收入时还没交税
  • 自产的货物用于在建工程增值税
  • 视同销售是填在申报表的哪一栏?
  • 银行代发工资流失原因
  • 小规模纳税人的税率是多少
  • 小规模季度超过45万了怎么缴纳
  • 企业向个人的借款合同
  • 房地产竣工验收后结转收入和成本
  • 参加新冠疫情防控工作总结
  • 办公设备维修费会计分录
  • 银行保函会计处理
  • 所得税审核一般需要多久
  • 已经认证的进项票销售方冲红了
  • 小规模纳税人收入不能超过多少
  • 哪些业务需要计提国别风险准备金
  • 数据库sql分组
  • w8远程桌面连接
  • win8关机后自动重启怎么办
  • xp系统的存储在哪里
  • 苹果官网
  • win8 开机
  • 苹果电脑旋转屏幕设置在哪里找
  • CentOS救援模式实验笔记详解
  • windows8.1开机
  • mac 无线网
  • windows7搭建ftp
  • win10如何创建一个新的用户
  • win8 开始
  • opengl获取鼠标位置
  • Extjs中使用extend(js继承) 的代码
  • centos上安装邮件服务器
  • 使用vs code开发Django
  • 实用js代码
  • 国家税务总局2012年20号公告
  • 国家财政税务局
  • 长春购房契税税率
  • 年终奖发4万扣多少税
  • 环保税要求标注什么
  • 全国征兵网官网报名
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设