China DOS Union

-- Unite DOS · Advance DOS · Grow DOS --

Union site: www.cn-dos.net Forum site: www.cn-dos.net/forum
DOS stands for freedom, openness and progress. Let us work hard, learn from the openness and GNU spirit of FreeDOS and Linux, and together build and grow a free GNU GPL world!

中国DOS联盟论坛
The time now is 2026-06-24 05:10
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [Original] Detailed Explanation of Variable Delay (Recommended for Beginners) View 24,457 Replies 111
Original Poster Posted 2007-03-09 08:52 ·  中国 广东 中山 电信
初级用户
Credits 128
Posts 16
Joined 2007-01-26 04:00
19-year member
UID 77697
Gender Male
Status Offline

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 ]
Recent Ratings for This Post ( 27 in total) Click for details
RaterScoreTime
oilio +3 2007-03-09 09:09
electronixtar +8 2007-03-09 09:46
everest79 +8 2007-03-09 11:34
ieutk +2 2007-03-09 11:45
namejm +8 2007-03-09 11:57
amao +4 2007-03-09 18:59
lxmxn +10 2007-03-09 23:24
htysm +4 2007-03-12 22:39
redtek +10 2007-03-15 21:51
chenall +5 2007-03-22 13:08
fyb198351 +1 2007-04-29 22:31
jzcn +1 2007-04-30 21:30
yong119 +1 2007-06-05 11:37
hngaoshou +2 2007-06-20 20:22
Billunique +2 2007-09-18 14:53
ab200210 +2 2007-10-02 15:00
xx12212 +2 2007-10-02 17:18
uiopuiop +2 2007-10-05 22:14
zhct +2 2008-01-09 00:58
hy433124shc +2 2008-02-20 20:00
vivifier0923 +1 2008-04-09 23:39
fastrun +2 2008-07-09 15:25
haiou327 +8 2008-08-02 22:26
yyyyyyyyy +2 2008-08-26 11:08
mf1388 +1 2008-12-03 17:51
wuyugui +2 2010-04-17 09:25
ssgarlic +1 2010-12-28 23:03
Floor 2 Posted 2007-03-09 09:47 ·  中国 四川 成都 教育网
铂金会员
★★★★
Credits 7,493
Posts 2,672
Joined 2005-09-02 00:00
20-year member
UID 42173
Gender Male
Status Offline

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'>"
Floor 3 Posted 2007-03-09 09:52 ·  中国 江苏 连云港 联通
高级用户
★★★
前进者
Credits 641
Posts 303
Joined 2007-01-10 02:57
19-year member
UID 76009
Gender Male
Status Offline
Hehe, it's for beginners. I'll support you. It's not easy to write so much.
我相信总有一天,总会遇到一个人可以相濡以沫、相吻以湿!
Floor 4 Posted 2007-03-09 09:58 ·  中国 广东 中山 电信
初级用户
Credits 128
Posts 16
Joined 2007-01-26 04:00
19-year member
UID 77697
Gender Male
Status Offline
Finally posted, forgot to bump it myself~~! Haha
Thanks to predecessors electronixtar and oilio for your support!!
Floor 5 Posted 2007-03-09 11:44 ·  中国 广东 东莞 电信
初级用户
Credits 107
Posts 48
Joined 2006-11-30 12:06
19-year member
UID 72174
Gender Male
Status Offline
Thank you, the LZ. Such posts are the best for newcomers. Newcomers are fortunate!
Floor 6 Posted 2007-03-09 11:57 ·  中国 广东 电信
荣誉版主
★★★★
batch fan
Credits 5,226
Posts 1,737
Joined 2006-03-10 00:38
20-year member
UID 51697
From 成都
Status Offline
Well written, very helpful for beginners, included in the classic post index.
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
Floor 7 Posted 2007-03-09 16:58 ·  中国 广东 广州 电信
初级用户
★★
Credits 197
Posts 77
Joined 2006-09-19 14:02
19-year member
UID 63074
Gender Male
Status Offline
Floor 8 Posted 2007-03-09 18:39 ·  中国 河北 邢台 联通
新手上路
Credits 2
Posts 1
Joined 2007-03-07 11:32
19-year member
UID 81003
Gender Male
From 邢台
Status Offline
It's really good, just too long. I'm afraid it's hard to understand, but it's still good. Up!!!
Floor 9 Posted 2007-03-09 23:01 ·  中国 安徽 马鞍山 电信
中级用户
★★
Credits 493
Posts 228
Joined 2007-02-16 00:38
19-year member
UID 79596
Gender Male
From 安徽
Status Offline

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!
Floor 10 Posted 2007-03-09 23:49 ·  新西兰
初级用户
Credits 107
Posts 47
Joined 2007-03-03 03:12
19-year member
UID 80618
Gender Male
Status Offline
Yay````Suitable for beginners like me
Floor 11 Posted 2007-03-10 10:44 ·  中国 广东 东莞 电信
新手上路
Credits 18
Posts 10
Joined 2006-12-20 17:52
19-year member
UID 74059
Gender Male
Status Offline
What a great post~ thanks to the LZ's analysis!
Floor 12 Posted 2007-03-10 21:04 ·  中国 安徽 阜阳 电信
初级用户
Credits 42
Posts 19
Joined 2006-12-28 01:20
19-year member
UID 74752
Gender Male
Status Offline
Floor 13 Posted 2007-03-12 22:40 ·  中国 安徽 芜湖 电信
高级用户
★★★
Credits 866
Posts 415
Joined 2005-12-04 11:19
20-year member
UID 46459
Status Offline
I like the LZ. Strong. DOS Union is fortunate.
Floor 14 Posted 2007-03-13 01:41 ·  中国 广东 深圳 宝安区 电信
高级用户
★★★
Credits 793
Posts 312
Joined 2004-09-02 00:00
21-year member
UID 31104
Gender Male
Status Offline
The post is good, I've learned something.
Floor 15 Posted 2007-03-13 01:44 ·  中国 广东 深圳 宝安区 电信
高级用户
★★★
Credits 793
Posts 312
Joined 2004-09-02 00:00
21-year member
UID 31104
Gender Male
Status Offline
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.
1 2 3 8 Next ›
Forum Jump: