|
nforce1
初级用户
 
积分 128
发帖 16
注册 2007-1-26
状态 离线
|
  『楼 主』:
[原创]变量延迟详解(新手推荐)
使用 LLM 解释/回答一下
因工作关系一直没有太多时间泡在论坛上,每次上本论坛都很匆忙,注册几个月以来第一次发贴(因为本人太菜,不敢发帖),真有点不好意思!希望大家多多支持!
本帖只“照顾”新手,老鸟略过,哈!
以下是偶根据论坛内的帖子得出的结论,如有错漏敬请指正!
首先要特别感谢willsort老大写的这帖子,偶是从中得到启发的!
http://www.cn-dos.net/forum/viewthread.php?tid=20733
下面在讨论过程中,偶会插入一些“废话”,如果你不喜欢看我写的“废话”,可以跳过。它与本文讨论的中心完全无关!不过偶还是建议大家看看,哈!
这段可跳过:
同学们上课啦,第一天来这里任教,必须先做个自我介绍。偶叫金城武,啊啊~~~~~~不,不是,一时口快说错了, 偶姓贾,不好意思!由于近日忙于研究“鬼武者”,所以忘了自己的姓氏!什么,说我现在才玩鬼武者,哎!没办法啊,偶穷啊,口袋里总是掏不起这几块钱买啊。“几块钱?”众人议论纷纷。什么,又说我买盗版,啊~~啊~~~这~~这不在本文的讨论范围啊~~~~~说完台下众人举起砖头……^_^
这是正文不可跳过:
willsort老大上面的帖子,对于新手来说比较难理解。不过没关系,我们先分析一个例子,同样是引用willsort老大的。本例启用了变量延迟,是个正确的例子!
例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”字符串,下面将讲解每个语句的意思:
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 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
这和前面的例子差不多,只是所有!号都换成%号,这是个错误的例子。因为它没有启用变量延迟,也没有使用!号把变量括起来。我们看到它的执行结果是显示“ECHO 处于关闭状态”。
为什么会这样呢?原因是,在没有启用变量延迟的情况下,凡是在括号内(即do里面)的变量,在执行for语句之前,就已经被替换成for语句之前其它命令对该变量所赋予的值。
则是说在本例中的以下几句
set n=%%i
set n=%n:ld.=t%
set n=%n:o w= S%
set n=%n:He=Wi%
echo %n%
第一句能正常执行并达到它的目的,因为它只是单纯地将%%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。
启用变量延迟后,在执行
set n=!n:ld.=t!
set n=!n:o w= S!
set n=!n:He=Wi!
echo !n!
这些语句前,它们里面的变量n不会马上被CMD替换(启用延迟后,CMD变得有耐性啦^_^),而未被替换的话,那么n就还是变量,而不是常量。等到执行set n=!n:ld.=t!等这几句时,变量n才被替换。这样每个set命令都能感知变量n的任何变化,从而作出正确的替换行为。这就是变量延迟啦!
可跳过:
什么,说我讲得不好?没办法啊,因为偶太菜啊,只知道这些。偶只是淘两顿饭吃而已,望大家谅解啊,不要再拿砖头砸偶。。。不然偶就~~~~~~~~~~叫救命!^_^
这是正文不可跳过:
不要以为只有for才要用变量延迟,下面这个例子同样需要
例3:这是个错误的例子
@echo off
set mm=girl&echo %mm%
pause
执行后依然显示“ECHO 处于关闭状态”。
原因是没有启用延迟,而且在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命令就显示什么值。
大家这样做就明白了:
@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)对变量mm做了什么“坏事”,从而作出正确的判断并执行
好了全篇完了,下课!
突然,门外传来几只“恐龙”的嚎叫声:把那小子抓回去,胆敢趁着节日咱们游山玩水的时候偷走!!
2分钟后,“恐龙战队”押着这小子来到一个美丽壮观的“城堡”面前,正门上方写着“XX疯人院”,哈哈!
愿天下美女妇女节快乐,一天比一天美(包括在浏览本贴的你)!!---汗,这里有女同胞吗??有的请举手!呵呵!39们也一起感受节日的气氛吧!
这帖本来是想上午发的,但因工作关系,到现在才有空,无奈啊!
以上这些“废话”只是想令大家阅读这贴时能增添几分气氛,增加大家的阅读兴趣,令大家在学习过程中轻松轻松而已。如有得罪,敬请批评指正!
Last edited by nforce1 on 2007-4-2 at 09:26 AM ]
Due to work reasons, I haven't had much time to be in the forum. Every time I come to this forum, it's very hurried. This is the first post I've made since registering for a few months (because I'm too noob to post), and I'm really a bit embarrassed! I hope everyone will support me a lot!
This post only "caters" to newcomers, and veterans can skip it, haha!
The following are the conclusions I drew based on the posts in the forum. Please correct any errors or omissions!
First of all, I would like to especially thank the post written by Boss willsort. I got inspiration from it!
http://www.cn-dos.net/forum/viewthread.php?tid=20733
In the following discussion process, I will insert some "nonsense". If you don't like reading my "nonsense", you can skip it. It has nothing to do with the central discussion of this text! But I still suggest that everyone take a look, haha!
This part can be skipped:
Class is in session, everyone! On the first day of teaching here, I must first introduce myself. My name is Jin Chengwu, uh~~~~~~ no, no, I said it wrong in a moment of carelessness. My surname is Jia, sorry! Because I've been busy studying "Onimusha" recently, so I forgot my surname! What, you say I'm just playing Onimusha now, hey! There's no way, I'm poor, and I can't always afford to buy these few dollars. "A few dollars?" Everyone discussed. What, you say I bought a pirated version, ah~~ ah~~~ this~~ this is not within the scope of this discussion~~~~~ After speaking, everyone in the audience raised bricks... ^_^
This is the main text and cannot be skipped:
Boss willsort's above post is relatively difficult for newcomers to understand. But it's okay, let's first analyze an example, which also quotes Boss willsort. This example enables variable delay and is a correct example!
Example 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
After saving the above code as a.bat and double-clicking to execute it, the string "Will Sort" will be displayed. The following will explain the meaning of each statement:
1.@echo off & setlocal EnableDelayedExpansion
Turn off command echo and enable variable delay
2.for /f "tokens=* delims=" %%i in ("Hello world.") do (
The use of the for command and its parameters, please search for related words in the forum. Due to space limitations, it will not be discussed here. If you don't understand its meaning at this time, then just treat it as its function is to assign the string "Hello world." to %%i. Of course, this is just a temporary measure, and you must learn to use for in the future!
3.set n=%%i
Assign the value of %%i (that is, Hello world.) to variable n. Everyone knows this, right?
4.set n=!n:ld.=t!
Here, we need to talk about the function of set replacing characters. The meaning of this statement is to first get the value of variable n (at this time, the value of n is "Hello world."), then replace the character "t" with the character "ld.", and then assign the replaced result to variable n again (at this time, the value of n becomes "Hello wort"). As for the writing format of set replacing characters, you can type "set/?" in CMD to find the part where "%PATH:str1=str2%" is explained.
5.set n=!n:o w= S!
The meaning is the same as the previous sentence, but the content of replacement and being replaced is different. It replaces " S" with "o w" (note that there is a space before S and before w). In fact, Boss willsort wants to prove that set replacing characters support periods and spaces (there is a. after "ld" in the 4th sentence). At this time, the value of n is "Hell Sort".
6.set n=!n:He=Wi!
Needless to say, after executing this sentence, the value of n is "Will Sort".
7.echo !n!
Display the value of variable n.
It should be noted that once variable delay is enabled, the variable must be enclosed in! instead of %.
Okay, the meaning of each sentence has been explained. Now, we need to talk about the variable delay issue that this post is really going to discuss.
Here, we need to quote Boss Will Sort's explanation: When CMD reads the for statement, all the statements enclosed in a pair of parentheses after it will be read together and necessary preprocessing work will be completed, which includes the expansion of environment variables. So before all the statements in the for are executed, all environment variables have already been replaced with the values set before the for, thus becoming a string constant and no longer a variable.
And in order to be able to sense the dynamic changes of environment variables inside the for statement, CMD designed the delayed environment variable expansion feature, that is, when CMD reads a complete statement, it will not immediately perform the variable expansion behavior, but will perform the expansion before a single statement is executed, that is, this expansion behavior is "delayed".
In general, without enabling variable delay, for variables inside parentheses (that is, inside do), before executing the for statement, they have already been replaced with the values that other commands have assigned to the variable before the for statement. It doesn't matter if you don't understand this sentence. Let's look at another example below, and you will understand after reading it.
Example 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
This is similar to the previous example, but all! are replaced with %, which is a wrong example. Because it doesn't enable variable delay and doesn't use! to enclose the variable. We can see that its execution result is to display "ECHO is off".
Why is this? The reason is that without enabling variable delay, for variables inside parentheses (that is, inside do), before executing the for statement, they have already been replaced with the values that other commands have assigned to the variable before the for statement.
That is to say, the following sentences in this example
set n=%%i
set n=%n:ld.=t%
set n=%n:o w= S%
set n=%n:He=Wi%
echo %n%
The first sentence can be executed normally and achieve its purpose because it simply assigns the value of %%i to variable n, so there is no problem. The other sentences are like this: Long before the for statement is executed, CMD is in a hurry to perform the replacement behavior of all variables n in these sentences together, replacing them with the values that other commands have set for n before the for, thus making n a constant. But in this example, before the for statement, there is only the @echo off sentence, and no other commands have assigned any value to n. So before the for, the value of variable n is an empty value. That is to say, the variable n in the sentence set n=%n:ld.=t% is immediately replaced with an empty value by CMD after reading (note that it is reading, not executing) the entire for statement (at this time, it hasn't reached the set to perform its own task yet). There is nothing in an empty value, so there is no such thing as replacing one character with another (how can you replace without anything?). Finally, when executing the sentence set n=%n:ld.=t%, it just gets an empty value and assigns an empty value to variable n. The same principle applies to the other sentences.
So, when finally echoing %n%, variable n is still an empty value, and the echo command has nothing to display, so it just displays the sentence "ECHO is off" to explain its state.
Through the explanation of this example, I believe everyone already knows the role of variable delay! Let's look back at Example 1.
After enabling variable delay, when executing
set n=!n:ld.=t!
set n=!n:o w= S!
set n=!n:He=Wi!
echo !n!
Before these sentences are executed, the variable n inside them will not be replaced immediately by CMD (after enabling delay, CMD becomes patient ^_^), and if it is not replaced, then n is still a variable, not a constant. Wait until these sentences such as set n=!n:ld.=t! are executed, then variable n is replaced. In this way, each set command can sense any change of variable n and make the correct replacement behavior. This is variable delay!
This part can be skipped:
What, you say I'm not doing well? There's no way, because I'm too noob, I only know these. I'm just trying to earn two meals, please understand, don't throw bricks at me again... Otherwise, I will~~~~~~~~~~ call for help! ^_^
This is the main text and cannot be skipped:
Don't think that only for needs variable delay. The following example also needs it.
Example 3: This is a wrong example
@echo off
set mm=girl&echo %mm%
pause
After execution, it still displays "ECHO is off".
The reason is that there is no enabling delay, and there is no other command to assign a value to mm before the sentence set mm=girl&echo %mm%. At this time, when CMD executes the sentence set mm=girl&echo %mm% before, it has already been in a hurry to replace the value of variable mm, and because there is no assignment to mm before, mm is replaced with an empty value and becomes a constant. When the echo command is executed, it is actually echoing a constant that will not change, which is an empty value in this example.
Some people will ask, isn't mm assigned a value before echo?
This is related to the step of CMD interpreting the command. You can refer to the post by willsort at the beginning of this post.
In general, if variable delay is not enabled, in this example, echo will not care or know whether there is another command to assign a value to mm in front of it (referring to the same line of statement). It will only obtain the content of the variable it wants to display from the statement above set mm=girl&echo %mm%, that is, the command on the previous line or a few lines sets mm to what value, and the echo command will display what value.
Everyone can understand it by doing this:
@echo off
set mm=boy
set mm=girl&echo %mm%
pause
See what the result is!
This is the correct way to write Example 3:
@echo off&setlocal EnableDelayedExpansion
set mm=girl&echo !mm!
pause
After enabling variable delay, the behavior of variable expansion (replacement) is delayed until the echo command is executed. At this time, echo can sense what "bad things" the previous command (the set in this example) has done to variable mm, and thus make the correct judgment and execute.
Okay, the whole article is over, class is over!
Suddenly, the howls of a few "dinosaurs" came from outside the door: Catch that kid back, how dare you steal while we are enjoying mountains and waters during the festival!!
Two minutes later, the "Dinosaur Team" escorted this kid to a beautiful and spectacular "castle" in front. The door above the main entrance read "XX Lunatic Asylum", haha!
Wish all beautiful women a happy Women's Day, and be more beautiful every day (including you who are browsing this post)! -- Sweat, are there female comrades here? Those who are please raise your hands! Hehe! The 39s also feel the festive atmosphere together!
This post was originally intended to be posted in the morning, but due to work reasons, I only have time now, so helpless!
The above "nonsense" is just to make everyone feel more festive when reading this post, increase everyone's reading interest, and make everyone relax during the learning process. If there is any offense, please criticize and correct!
Last edited by nforce1 on 2007-4-2 at 09:26 AM ]
此帖被 +96 点积分 点击查看详情 评分人:【 oilio 】 | 分数: +3 | 时间:2007-3-9 09:09 | 评分人:【 electronixtar 】 | 分数: +8 | 时间:2007-3-9 09:46 | 评分人:【 everest79 】 | 分数: +8 | 时间:2007-3-9 11:34 | 评分人:【 ieutk 】 | 分数: +2 | 时间:2007-3-9 11:45 | 评分人:【 namejm 】 | 分数: +8 | 时间:2007-3-9 11:57 | 评分人:【 amao 】 | 分数: +4 | 时间:2007-3-9 18:59 | 评分人:【 lxmxn 】 | 分数: +10 | 时间:2007-3-9 23:24 | 评分人:【 htysm 】 | 分数: +4 | 时间:2007-3-12 22:39 | 评分人:【 redtek 】 | 分数: +10 | 时间:2007-3-15 21:51 | 评分人:【 chenall 】 | 分数: +5 | 时间:2007-3-22 13:08 | 评分人:【 fyb198351 】 | 分数: +1 | 时间:2007-4-29 22:31 | 评分人:【 jzcn 】 | 分数: +1 | 时间:2007-4-30 21:30 | 评分人:【 yong119 】 | 分数: +1 | 时间:2007-6-5 11:37 | 评分人:【 hngaoshou 】 | 分数: +2 | 时间:2007-6-20 20:22 | 评分人:【 Billunique 】 | 分数: +2 | 时间:2007-9-18 14:53 | 评分人:【 ab200210 】 | 分数: +2 | 时间:2007-10-2 15:00 | 评分人:【 xx12212 】 | 分数: +2 | 时间:2007-10-2 17:18 | 评分人:【 uiopuiop 】 | 分数: +2 | 时间:2007-10-5 22:14 | 评分人:【 zhct 】 | 分数: +2 | 时间:2008-1-9 00:58 | 评分人:【 hy433124shc 】 | 分数: +2 | 时间:2008-2-20 20:00 | 评分人:【 vivifier0923 】 | 分数: +1 | 时间:2008-4-9 23:39 | 评分人:【 fastrun 】 | 分数: +2 | 时间:2008-7-9 15:25 | 评分人:【 haiou327 】 | 分数: +8 | 时间:2008-8-2 22:26 | 评分人:【 yyyyyyyyy 】 | 分数: +2 | 时间:2008-8-26 11:08 | 评分人:【 mf1388 】 | 分数: +1 | 时间:2008-12-3 17:51 | 评分人:【 wuyugui 】 | 分数: +2 | 时间:2010-4-17 09:25 | 评分人:【 ssgarlic 】 | 分数: +1 | 时间:2010-12-28 23:03 |
|
|
|
2007-3-9 08:52 |
|
|
electronixtar
铂金会员
      
积分 7493
发帖 2672
注册 2005-9-2
状态 离线
|
『第 2 楼』:
使用 LLM 解释/回答一下
顶,沙发
|

C:\>BLOG http://initiative.yo2.cn/
C:\>hh.exe ntcmds.chm::/ntcmds.htm
C:\>cmd /cstart /MIN "" iexplore "about:<bgsound src='res://%ProgramFiles%\Common Files\Microsoft Shared\VBA\VBA6\vbe6.dll/10/5432'>" |
|
2007-3-9 09:47 |
|
|
oilio
高级用户
    前进者
积分 641
发帖 303
注册 2007-1-10
状态 离线
|
『第 3 楼』:
使用 LLM 解释/回答一下
呵呵,是写给新手看的,支持你一下。写这么多也不容易。
Hehe, it's for beginners. I'll support you. It's not easy to write so much.
|

我相信总有一天,总会遇到一个人可以相濡以沫、相吻以湿! |
|
2007-3-9 09:52 |
|
|
nforce1
初级用户
 
积分 128
发帖 16
注册 2007-1-26
状态 离线
|
『第 4 楼』:
使用 LLM 解释/回答一下
好不容易发帖,忘了自己顶一个~~!哈
谢谢electronixtar与 oilio两位前辈的支持!!
Finally posted, forgot to bump it myself~~! Haha
Thanks to predecessors electronixtar and oilio for your support!!
|
|
2007-3-9 09:58 |
|
|
ieutk
初级用户
 
积分 107
发帖 48
注册 2006-11-30
状态 离线
|
『第 5 楼』:
使用 LLM 解释/回答一下
谢谢楼主,这样的贴子对新手最好了,新手有福啦!
Thank you, the LZ. Such posts are the best for newcomers. Newcomers are fortunate!
|
|
2007-3-9 11:44 |
|
|
namejm
荣誉版主
       batch fan
积分 5226
发帖 1737
注册 2006-3-10 来自 成都
状态 离线
|
『第 6 楼』:
使用 LLM 解释/回答一下
写得不错,对新手会很有帮助,收入经典帖子索引。
Well written, very helpful for beginners, included in the classic post index.
|

尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。 |
|
2007-3-9 11:57 |
|
|
bbq123bbq
初级用户
 
积分 197
发帖 77
注册 2006-9-19
状态 离线
|
|
2007-3-9 16:58 |
|
|
liujunhjl
新手上路

积分 2
发帖 1
注册 2007-3-7 来自 邢台
状态 离线
|
『第 8 楼』:
使用 LLM 解释/回答一下
写的真不错,就是太长了,就怕看不懂,不过还是不错的,顶!!!!!
It's really good, just too long. I'm afraid it's hard to understand, but it's still good. Up!!!
|
|
2007-3-9 18:39 |
|
|
xycoordinate
中级用户
  
积分 493
发帖 228
注册 2007-2-16 来自 安徽
状态 离线
|
『第 9 楼』:
使用 LLM 解释/回答一下
这里又要引用Will Sort老大的说明:当CMD读取for语句时,其后用一对圆括号闭合的所有语句将一同读取,并完成必要的预处理工作,这其中就包括环境变量的扩展,所以在for中的所有语句执行之前,所有的环境变量都已经被替换为for之前所设定的值,从而成为一个字符串常量,而不再是变量。
而为了能够在for语句内部感知环境变量的动态变化,CMD设计了延迟的环境变量扩展特性,也就是说,当CMD读取了一条完整的语句之后,它不会立即执行变量的扩展行为,而会在某个单条语句执行之前再进行扩展,也就是说,这个扩展行为被“延迟”了。
总的来说是,在没有启用变量延迟的情况下,凡是在括号内(即do里面)的变量,在执行for语句之前,就已经被替换成for语句之前其它命令对该变量所赋予的值。这句话不懂没关系,下面再看一个例子,看完你就会明白。
21世纪最缺什么?
。。。。。。
道理很多人都知道,但是能够说明白,让更多的人知道,
一个字:难!
Here we need to quote the explanation from Boss Will Sort: When CMD reads a for statement, all the statements enclosed in a pair of parentheses after it are read together and necessary preprocessing work is completed, which includes the expansion of environment variables. So before all the statements in the for are executed, all environment variables have already been replaced with the values set before the for, thus becoming a string constant, no longer a variable.
And in order to be able to sense the dynamic changes of environment variables inside the for statement, CMD designs the feature of delayed environment variable expansion. That is to say, when CMD reads a complete statement, it will not immediately perform the variable expansion behavior, but will perform the expansion before a single statement is executed, that is, this expansion behavior is "delayed".
In general, without enabling variable delay, all variables inside the parentheses (that is, inside do) are replaced with the values that other commands have assigned to the variable before the for statement is executed. It doesn't matter if you don't understand this sentence. Let's look at an example below, and you will understand after reading it.
What's the most lacking in the 21st century?
......
Many people know the truth, but being able to explain it clearly and let more people know,
One word: difficult!
|
|
2007-3-9 23:01 |
|
|
nzisisco
初级用户
 
积分 107
发帖 47
注册 2007-3-3
状态 离线
|
『第 10 楼』:
使用 LLM 解释/回答一下
好耶````适合我这种新手看
Yay````Suitable for beginners like me
|
|
2007-3-9 23:49 |
|
|
sbyguli
新手上路

积分 18
发帖 10
注册 2006-12-20
状态 离线
|
『第 11 楼』:
使用 LLM 解释/回答一下
好帖子啊~谢谢楼主的分析!
What a great post~ thanks to the LZ's analysis!
|
|
2007-3-10 10:44 |
|
|
shuaigeya
初级用户
 
积分 42
发帖 19
注册 2006-12-28
状态 离线
|
|
2007-3-10 21:04 |
|
|
htysm
高级用户
   
积分 866
发帖 415
注册 2005-12-4
状态 离线
|
『第 13 楼』:
使用 LLM 解释/回答一下
偶喜欢楼主.强.DOS联盟有福了.
I like the LZ. Strong. DOS Union is fortunate.
|
|
2007-3-12 22:40 |
|
|
willsion
高级用户
   
积分 793
发帖 312
注册 2004-9-2
状态 离线
|
『第 14 楼』:
使用 LLM 解释/回答一下
帖子不错,学习了。
The post is good, I've learned something.
|
|
2007-3-13 01:41 |
|
|
willsion
高级用户
   
积分 793
发帖 312
注册 2004-9-2
状态 离线
|
『第 15 楼』:
使用 LLM 解释/回答一下
另外,有个疑问,不知道变量延迟是否有副作用,如果没有副作用的话
,那每个程序头干脆插上setlocal EnableDelayedExpansion语句了。就象
@echo off一样。
In addition, there is a question. I don't know if variable delay has side effects. If there are no side effects, then each program header might as well insert the setlocal EnableDelayedExpansion statement. Just like @echo off.
|
|
2007-3-13 01:44 |
|
|