得之我幸 失之我命

when someone abandons you,it is him that gets loss because he lost someone who truly loves him but you just lost one who doesn’t love you.

setlocal enabledelayedexpansion

setlocal enabledelayedexpansion延迟变量全称延迟环境变量扩展,要理解这个东西,得先理解一下什么叫扩展.CMD在解释命令的时候,首先会读取命令行一条完整的命令,然后对其进行一些命令格式的匹配操作,判断所输入的命令格式是不是符合要求.如果要在命令中引用一些变量,那么如何让CMD在解释命令时,能识别出这个变量呢?

这时就可以在变量名字两边加一个%号,如%name%,当CMD在对读取这行命令进行格式匹配的时候,就会发现name这个字符两边加了%号,就不会把它当作普通字符处理,而是会把它当作一个变量处理,变量名叫name,然后CMD就会找到变量名对应的值,用变量名的值替换掉这个变量名字(name),(如果变量名不存在值,就返回空值),再将这个替换好并且匹配的命令执行,这个替换值的过程就叫做变量扩展,说白了就是把变量的名字,用它的值给替换掉后执行,也就是批处理如何识别一个变量的过程.

**注意:**这里只是变量的扩展的意思,不是延迟环境变量扩展,要理解延迟环境变量扩展,必须先理解什么是变量的扩展,也就是批处理如何识别一个变量的过程.
例如

1
2
set var=test
echo %var%

CMD在读取到echo %var%这句命令后,就会进行匹配操作,它马上就发现var字符两边有%号,这时就它会把它当作一个变量处理,查看这个var变量名是不是有值,如果有就用它的值把变量名var给替换掉,在上一条命令set var=test中,给var赋值为test,所以它会用test把%var%这个变量名替换掉,替换后的结果就为echo test了.这些步骤都是CMD进行匹配操作的步骤,匹配完后,它再执行echo test这条语句,这时CMD就会echo出一个test了.
什么是环境变量扩展知道了,那什么是延迟环境变量扩展呢?
在理解环境变量扩展时,得知了CMD在解释命令时,首先会把一条完整的命令进行读取,然后进行匹配操作,匹配时它会把命令里的变量用变量的值个替换掉,然后执行这个替换好的命令.
问题就出在一条完整的命令,在BAT中,IF FOR这样的命令都可以加括号,将一些命令嵌套在里面执行.这样的话对于一条可以加扩号嵌其它命令的命令,它的完整格式就是

1
for %%i in (....)

这样一个整体.此时,如果在括号里面嵌入一些设置变量值的命令,就会出现问题了.
例如

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

按理说执行结果应该是

1
2
3
4
5
1
2
3
4
5

但执行后却显示5个空行的错误提示,为什么?根据上面说的知识来理解下

1
2
3
4
5
6
@echo off
set var=test
for /l %%i in (1,1,5) do (
set var=%%i
echo %var%
)

这个就会打印5个test了,说明for /l %%i in (1,1,5) 没有起作用.
通过这两个例子,很明显如果只有环境变量扩展这个过程的话,在可以嵌套命令的命令中执行赋值操作时,会让BAT出现给变量赋值的问题.那么这个时候延迟环境变量扩展,这个概念就被提出来了.
在批处理中,可以用setloacl enabledelayedexpansion这个命令来启用延迟环境变量扩展.
启用了"延迟环境变量扩展"后,当CMD在解释含有嵌套格式的命令时,它会把嵌套的命令一条一条的先执行一次,然后再进行匹配操作,这样赋值操作就会完成.并且再"延迟环境变量扩展"启用后,CMD会用!号来判断这是不是一个变量,没启用,变量用%name%这样的格式判断,启用后就用!name!这样的格式判断,这个符号我们需要注意.
例如

1
2
3
4
5
6
7
@echo off
setlocal enabledelayedexpansion
set var=test
for /l %%i in (1,1,5) do (
set var=%%i
echo !var!
)

执行结果是

1
2
3
4
5
1
2
3
4
5

再例如

1
2
3
@echo off
set var=test & echo %test%
pause

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

1
2
3
4
@echo off
setlocal enabledelayedexpansion
set var=test & echo !var!
pause

be yourself, everyone else is already taken.