DOS environment variable delay extension enabledelayedexpansion detailed _dos/bat

Source: Internet
Author: User
Tags constant echo command extend

One, what is deferred environment variable extension?

Delay variable Full name "Delay environment variable extension", to understand this thing, we have to understand what is called variable expansion!
When we explain our command, CMD will first read a complete command, and then do some command format matching operation, see you entered the
The command format does not conform to its requirements. If we're going to refer to some variables in the command, how do we get cmd to recognize our command when interpreting it?
What about this variable? Then we can add a% to both sides of the variable name, such as%name%. When cmd reads our entire command for a format match
, you will find that the name of the character on both sides of the%, it will not be treated as a normal character, but it will be treated as a variable, the variable named name

Then CMD will find the value of the variable name, replace the variable name (name), (if the variable name does not exist, return null value). And then this
A replacement is good and the matching command executes! The process of replacing a value is called a variable extension, which means that the name of the variable is replaced with its value.
Execution! is the process of how batches recognize a variable. (Note: This is just the meaning of the extension of the variable, not the delay of the environment variable extension, to understand the deferred
Late environment variable expansion, you must first understand what is the extension of the variable is the batch processing how to identify a variable process.

Example 1,

@echo off
set var=test
echo%var%
Pause

CMD after reading to echo%var% This command, it will be matched operation, it immediately found that the Var character on both sides of the%, then CMD will take it as a
Variable to see if the VAR variable name has a value, and if so, replace the variable name var with this value, here our Var is in the previous command set
Var=test, the Var is assigned to test, so CMD replaces the variable name%var% with test, and the result of the replacement is echo test. These steps
All of these are CMD's steps to match the operation, after matching, he then executes ECHO test this statement, then our CMD will echo out a test.

What is an environment variable extension know, what is the delay environment variable extension?

In understanding the environment variable expansion, we know that cmd in the interpretation of the command, the first will be a complete command read, and then the matching operation, match
It replaces the variable in the command with the value of the variable, and then executes the replacement command. The problem is in "a complete command", in Bat, IF
For such a command can be bracketed, and some commands are nested inside to execute. In this case, for a command that can be embedded in another command, he finishes
The entire format is for the%%i in (...) Such a whole. At this point, if we embed in parentheses some command to set the value of the variable, it appears
The problem!

Example 2,

@echo off
for/l%%i in (1,1,5) do (
  set var=%%i
  echo%var%
)
Pause

5 blank line error prompts are displayed after execution! Why? We understand it according to the knowledge we have mentioned above.

With these two examples, you should have understood that if only the environment variables were to extend the process, if we were to execute in a command that could nest commands
When assigning operations, we get the bat to give the variable a problem. Then the concept of "delaying the environment variable extension" is proposed.

In batch processing, we can use Setloacl enabledelayedexpansion this command to enable "Delay environment variable extension", when we enable
After "Delay environment variable extension", when Cmd interprets a command with nested formatting, he executes the nested command one at a time before entering
Row matching operation, so that our assignment is done. And when the delay environment variable extension is enabled, CMD will use the! Number to determine if this is a variable
。 If not enabled before the variable with%name% such a format to judge, after the opening of the!name! in such a format to judge, this symbol we need to pay attention!

Example 3,

@echo off
setlocal enabledelayedexpansion
set var=1
for/l%%i in (1,1,5) do (
  set/a var =%%i 
  Echo!v ar!
)
Pause

So everyone should understand what is deferred environment variable expansion. Let's take another example.

Example 4,

@echo off
set Var=test & echo%test%
pause

This command is placed on one line, indicating that he is a complete command, and that "delay environment variable extension" is not enabled, and the above assignment error occurs!
OK now:

@echo off
setlocal enabledelayedexpansion
set Var=test & Echo!var!
Pause

Second, batch processing variable delay detailed

For the environment variable delay extension, use Set/? You can see some of the instructions, but given its poor translation level, it is recommended that before viewing the first
First CHCP 437 switch to English to view the original English description. Given the detailed text and several code examples, it should be easy to understand. Here only
Some supplements.

In many visible official documents, a pair of percent-closed environment variables are used to complete the substitution behavior of their values as "extensions" (expansion
", this is actually a first party concept, from the point of view of the command interpreter, and from the point of view of our users, it can be
As a reference (Reference), invocation (call), or fetch (GET).

The command interpreter, which extends the environment variables, is generally as follows: first, read a complete statement of the command line, and after some up-front preprocessing
, the command is matched with a percent-closed string before the execution is interpreted, and if a ring that matches the string is found in the ambient space
The boundary variable, then replaces the original string and the percent sign itself with its value, and replaces it with an empty string if it is not matched, and this process is the environment variable's
extension, which still belongs to the preprocessing scope of the command line.

A "complete statement" is interpreted in NT's command interpreter CMD as "for if Else" and a statement containing statement blocks and "& | && | |
"And so on, the composite statement.
Therefore, when CMD reads the FOR statement, then all statements closed with a pair of round numbers are read together and the necessary preprocessing is completed, which
Includes an extension of the environment variable, so all the environment variables have been replaced with the values that were set before all statements in the for are executed.
Thus becoming a string constant, not a variable. Regardless of how the environment variables are modified in the for, only the environment variables are really affected empty
, rather than within the for statement.

In order to be able to perceive the dynamic change of environment variables within the For statement, CMD designed the delay environment variable extension characteristic, that is, when Cmd reads
A complete statement, it does not immediately perform the extended behavior of the variable, but expands before a single statement is executed, i.e.
This extended behavior is "delayed".

The delay environment variable extension attribute is closed by default in CMD, and there are currently two ways to open it: one is Cmd/v:off (here is the wrong statement, should be
CMD/V:ON--NAMEJM note), it opens a new command-line shell, which is always valid until you exit the shell using exit.
Often used in the command line environment, and the second is setlocal enabledelayedexpansion, which restricts the modification of environment variables to local space,
After endlocal, the extended attributes and previous modifications to the environment variables disappear together and are often used in batch statements.


It is willsort to write a post for beginners is more difficult to understand. But it doesn't matter, we first analyze an example, the same is cited Willsort old
The big.

This example enables variable latency, which is the right 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

Save the above code as. Bat double-click execution displays the will Sort string, and the following explains 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 (  )
For the use of the command and its parameters, please search the forum for relevant words. Limited to the question of space, there is no discussion here. If you don't understand what it means right now,
Think, then you just think of it as the role of the string "Hello world." Assign value to%%i well, of course it's just a stopgap, and you'll have to learn for
The use!

3.set n=%%i
Assign the value of%%i (that is, Hello World) to the variable n, which everyone knows.

4.set n=!n:ld.=t!
Here is the function of the set substitution character. The meaning of this statement is to first get the value of the variable N (at which point the value of n is "Hello world.") ), and then
Replace the characters "T" with the character "LD." and then assign the replacement result again to the variable N (at which point the value of n changes to "Hello wort"). As for
Set substitution character writing format, you can type in cmd "set/?" Find the "%path:str1=str2%" section with the instructions.

5.set n=!n:o w= S!
The meaning is the same as the previous sentence, except that the replacement and the substituted content are different. It replaces "s" with "O W" (Note that there is a space in front of S and W), and its
The real Willsort boss is trying to prove that the set substitution character supports periods and spaces (the 4th sentence has a. After "LD"). The value of n now is "Hell Sort"


6.set n=!n:He=Wi!
Let's not say that, after executing this sentence, the value of N is "'ll Sort"

7.echo !n!
Show values for variable n

It should be noted that once the variable delay is enabled, it needs to be used! Number to enclose the variable instead of the% number.

Well, the meaning of each sentence has already been said, the following to talk about the real topic of the variable delay.
Here again, we'll quote will sort boss: when CMD reads the FOR statement, then all statements that are closed with a pair of parentheses are read together and complete
Necessary preprocessing, which includes an extension of the environment variable, so all the environment variables have been replaced before all statements in the for are executed
To a value that is set before a for, thus becoming a string constant, not a variable.

In order to be able to perceive the dynamic change of environment variables within the For statement, CMD designed the delay environment variable extension characteristic, that is, when Cmd reads
A complete statement, it does not immediately perform the extended behavior of the variable, but expands before a single statement is executed, which means that
An extended behavior is "delayed".

In general, in the absence of a variable delay, a variable in parentheses (that is, do), before executing the For statement, is
The value that the other command assigns to the variable before it is replaced with the for statement. This sentence does not understand does not matter, below see an example, after reading you will understand.

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, just all! Numbers are replaced by the%, which is a false example. Because it does not enable variable delay, it is not used!
Number to enclose the variable. We see that its execution results in "ECHO is off".
Why is that? The reason is that, in the absence of a variable delay, a variable in parentheses (that is, do), before executing the FOR statement
, it is already replaced with the value assigned to the variable by the other command prior to the for statement.

In this case, the following sentences

Set n=%%i
set n=%n:ld.=t%
set N=%n:o w= s%
set n=%n:he=wi%

The first sentence executes normally and achieves its purpose, because it simply assigns the%%i value to the variable n, so there is no problem. A few other lines of the genus
This situation: long before the For statement executes, CMD is anxious not to cut all the variable n in these sentences together to perform the substitution behavior, replace with for a for before,
The value set by the other command on N, so that n becomes a constant. But in this case, the FOR statement has only @echo off before, and there's no other command
Any assignment behavior to n, so the value of the variable n is null before the for.
That is to say, set n=%n:ld.=t% the variable n in this sentence, after the CMD read (note is read is not executed) complete a For statement (at this time not yet round
To set to perform its own task), is immediately replaced with a null value, a null value there is nothing inside, so there is no one character to replace another word
This statement of the character (how to replace the thing?) )。 Finally, when the set n=%n:ld.=t% statement is executed, it simply gets a null value and gives the variable n
Null value only. The other lines are the same principle.

So, when the last echo%n%, the variable n is still a null value, and the echo command has nothing to show, it only shows "Echo is off
"This sentence to illustrate his state of

Through this example, I believe that we already know the role of variable delay! Let's look at example 1 again.

When variable delay is enabled, the execution of the

Set n=!n:ld.=t!
Set N=!n:o w= s!
Set n=!n:he=wi!
Echo!n!

Before these statements, the variable n inside them is not immediately replaced by CMD (after enabling delay, cmd become patient ^_^), but not replaced, then n
It's still a variable, not a constant. The variable n is not replaced until the following sentences are executed, such as set n=!n:ld.=t!. So that each set command can perceive variables
n any change, thus making the correct substitution behavior. This is the variable delay!

Do not assume that only for the use of variable delay, the following example also requires

Example 3, this is an example of a mistake

@echo off
set Mm=girl&echo%mm%
Pause

"ECHO is turned off" is still displayed after execution.

The reason is that delay is not enabled, and no other commands are assigned to MM before the set Mm=girl&echo%mm% statement. Then when CMD executes the set
Mm=girl&echo%mm% statement before, it has been urgent not to cut the value of the variable mm replaced, and because the front did not give mm value, so mm was replaced with empty
Value, which becomes a constant. When the echo command is executed, it is actually a constant that does not change, in this case, a null value.

Some people will ask, is not the echo before the MM assigned value it?
This is related to cmd interpretation of the order of the steps, we can participate in detail this post at the beginning of Willsort.

In general, if the variable delay is not enabled, in this case, the echo will not notice or know whether the preceding (the same line of statements) has its
It commands to assign a value to mm. It will only get the contents of the variable that it wants to display from the statement above the set Mm=girl&echo%mm%, that is, the
What value does the echo command display when the command for a row or rows sets the value of MM.

This is what everyone knows:

@echo off
set Mm=boy
set Mm=girl&echo%mm%
Pause

Let's see what the results show!

This will be the correct example of writing 3:

@echo off&setlocal enabledelayedexpansion
set Mm=girl&echo!mm!
Pause

When a variable delay is turned on, the behavior of the variable extension (substitution) is deferred until the echo command is executed, when Echo senses the previous command (set in this example)
What do you do to the variable mm "bad" to make the right judgments and perform

Third, batch processing delay variable (popular explanation)

Variable delay setlocal enabledelayedexpansion
One of the most novice headaches, online tutorials, although many, but most of them are not understand, there are too many professional terminology.
Take the willsort of the Cn-dos alliance as an example, (personally considered to be the most authoritative and professional explanation)

But it may be because of professional, so I do not understand, because the study of CMD batch processing is not necessarily to learn computer professional. This ghost thing is really not good.
Understanding, in the next is also a lot of work, summed up a little experience, is now used to explain the popular method, hoping to give beginners some help, old birds laughed
, if there is a wrong place, please point out.

Anyway
When you need a delay variable, and how to refer to the delay variable, I think that's what most beginners desperately want to know.
I think it would be helpful for you to read the following things patiently.

To understand the delay variable, first you have to understand what is "compound statement" seems to have a "professional" noun, don't worry, this is very good understanding. Called
"Compound statement" means all the commands in a pair (). Like for the Do behind
Such as:

for/f "delims="%%i in (a.txt) do (
   set var=%%i
   echo%%i
   set num=%%i
)

Here are the three commands behind do, in a pair (), this is called "compound statement", of course, more than for and if and so on ...
Such as:

If "%var%" = = "abc" (
  echo OK
  set lis=123
)

Anyway, all the commands in the () are called "compound statements".
In addition: This is also compound statement set Abc=123&echo%abc% Yes, the command connected through the Pipe Command & is also a compound statement.

OK, now that you know the compound statement, you're going to start talking about the delay variable, which means that you want to use the delay variable in the compound statement.
We're not going to understand what it's called "Extension of variables." This thing is so professional, I don't quite understand it.

As long as we know when we need to use the delay variable, how to correctly extract the variables we need is OK, this is our goal.
CMD in the process of "compound statement", if the "compound statement" using a variable, the value of the variable as a compound statement before the value of the variable to reference
。 If the variable has not been assigned before, treat it as a null value.

Example 1,

@echo off
for/l%%i at (1 1) Do (
  set var=%%i
  echo%var%
)
Pause

Run the above code, show what? Displays 10 echo is in the closed state. By logic, the value of Var should be 1, 2, and 3........10
That's right!

This is because the delay variable is not open, and cmd refers to the value of Var as the value before the compound statement.
In this case, the compound statement is not defined for Var, so the value of Var is empty, so 10 echo is turned off.

Example 2,

@echo off
set var=abc
for/l%%i at (1 1) Do (
  set var=%%i
  echo%var%
)
Pause

Run the above code, will show what, you should know?

Example 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

After running the above code, the values assigned in the compound statement are all displayed, what does that mean?

Note that in a compound statement, you don't have to assign a value to a variable, but if you don't open the delay variable, you can't extract it in the compound statement to
When the compound statement is finished, it can be extracted.

Variables are represented in two ways: 1,%var% 2,!var!
The first type of representation, as we all know, is the second type of variable that references the delay.
In the case where the delay variable is turned on, it is possible to represent any method outside the compound statement. But you want to reference the compound in a compound statement
The second way is to get the variable immediately. See examples

Example 4,

@echo off
setlocal enabledelayedexpansion
set var=abc
for/l%%i in (1 1) Do (
  set var=%%i
  echo%va r%
  echo!var!
)
Pause

Note: The example has two echo one is the display%var% one is the display!var!
As it turns out,%var% shows the value of the variable var before the compound statement, and!var! Displays the values that are immediately available in the compound statement.

Example 5,

@echo off
setlocal enabledelayedexpansion
for/l%%i at (1 1 5) Do (
  set var%%i=%%i
)
Echo%var1% %var2%%var3%%var4%%var5%
echo!var1!!var2!
!var3!!var4!!var5! Pause

What does this example say, no more explaining?
shows that when a delay variable is turned on, and outside the compound statement, the variable can be represented in both ways. Let's talk about it. The explanations above, the end
It is all out of personal understanding, but also for the convenience of the professionals to understand that there must be a mistake in the place, like learning English, for the convenience of memory, with the Han
The pronunciation of the word to explain the same. Oh, is a "partial door" you are not new to the above said as a "truth", otherwise it becomes "
Misleading. "


Four. When do I use a delay variable? How to use it?

When do I use deferred variables? How to use it? These have always been to make the novice confused place, what exactly is it? Take a look at the following example,
We will guide you step-by-step.

Example 1,

@echo off
set/a num=0
for/l%%i at (1 1 3) do (
   Rem ================================
   set/a num =1 
   R EM is the value of the variable num each time plus 1
   Rem ================================
   echo%num%
)
Pause>nul

Let's guess, what's the result after the run? Do you think it will show: 1 2 3? I think most people would think so. You will again in
The code is saved as a batch file, run, and see the results.
As you can see, the results are not expected to be 1 2 3 but 0 0 0.

This is because batch processing, in the case of a variable in a for or if statement, is preceded by a preprocessing of the variable in percent%, first
Replace with the variable before the statement (such as the code above, the%num% in the For statement has long been replaced with the value before the statement: 0), so the For statement runs
, although the variable has been added 1, the value is unchanged (since the%num% in the Echo%num% has already been replaced by 0).
So, to implement real-time changes to variables in (for or if) statements (like here, I'm going to show 1 2 3) What do I do? It's going to start.
With deferred variables, first declare in batch: Setlocal Enabledelayedexpansion Then, the statement: Echo%num% to!num! (also
is to change "%" to "!" , so that you can achieve the results, the demo code:

Example 2,

@echo off 
Rem '///////first declare the delay variable/////////////
setlocal enabledelayedexpansion
set/a for
/ L%%i in (1 1 3) do (
   rem ================================
   set/a num =1 
   rem variable num each time plus 1
   rem ============ ====================
   Rem ' '//////////////////The following variables cannot be enclosed in "%", but should use "!"
   echo!num!
)
Pause>nul


Inductive Summary:
1, why use the delay variable?
Let the If statement and the variable in the For statement change in real time;

2, when to use the delay variable?
Typically used in a for statement and an if statement;

3, how to use the delay variable?
The delay variable is declared in the batch process first: Setlocal enabledelayedexpansion
Then use the For statement, the variable in the IF statement with two "!" You can enclose it.

4, in fact, the use of variable nested variables can also use variable delay.

Example 3,

@echo off
set a=1
set b1=10
echo%b%a%%
Pause

Perform display, get%b1%

In fact, I want to give the value of B1, that is 10 how to achieve it? The above example is modified as follows,

Example 4,

@echo off
set a=1&set b1=10
call,echo%%b%a%%%
Pause>nul

Call here is actually to rearrange the command line to expand, first expand the%%b%a%%% inside the%a%, so that%a% into a value of 1, and then use CAL to extend%b1%

You can also use variable delay to implement the following methods:

Example 5,

@echo off
set/a a=1,b1=10
Setlocal enabledelayedexpansion
echo:!b%a%! ...
Pause


Call's usage here is actually a shortcut to variable latency, which is generally used in a for loop body.
call,%%b%a%%% here the comma is actually a delimiter, and as with a space, there are many delimiters available, such as the echo:!b%a%! in the previous example ,
Of course, not all commands can be used in this way, depends on the situation ...


Example 6,

@echo off&setlocal enabledelayedexpansion
set a=1000
set B=DD
set a%b%=9000
set c=!a%b%! 
echo%c%
Pause

Execute it and see what it shows? Why is that? Believe that through example 4, example 5 you can also analyze it?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.