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延迟变量全称延迟环境变量扩展,要理解这个东西,得先理解一下什么叫扩展.CMD在解释命令的时候,首先会读取命令行一条完整的命令,然后对其进行一些命令格式的匹配操作,判断所输入的命令格式是不是符合要求.如果要在命令中引用一些变量,那么如何让CMD在解释命令时,能识别出这个变量呢?
这时就可以在变量名字两边加一个%号,如%name%,当CMD在对读取这行命令进行格式匹配的时候,就会发现name这个字符两边加了%号,就不会把它当作普通字符处理,而是会把它当作一个变量处理,变量名叫name,然后CMD就会找到变量名对应的值,用变量名的值替换掉这个变量名字(name),(如果变量名不存在值,就返回空值),再将这个替换好并且匹配的命令执行,这个替换值的过程就叫做变量扩展,说白了就是把变量的名字,用它的值给替换掉后执行,也就是批处理如何识别一个变量的过程.
**注意:**这里只是变量的扩展的意思,不是延迟环境变量扩展,要理解延迟环境变量扩展,必须先理解什么是变量的扩展,也就是批处理如何识别一个变量的过程.
例如
1 | set var=test |
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 | @echo off |
按理说执行结果应该是
1 | 1 |
但执行后却显示5个空行的错误提示,为什么?根据上面说的知识来理解下
1 | @echo off |
这个就会打印5个test了,说明for /l %%i in (1,1,5) 没有起作用.
通过这两个例子,很明显如果只有环境变量扩展这个过程的话,在可以嵌套命令的命令中执行赋值操作时,会让BAT出现给变量赋值的问题.那么这个时候延迟环境变量扩展,这个概念就被提出来了.
在批处理中,可以用setloacl enabledelayedexpansion这个命令来启用延迟环境变量扩展.
启用了"延迟环境变量扩展"后,当CMD在解释含有嵌套格式的命令时,它会把嵌套的命令一条一条的先执行一次,然后再进行匹配操作,这样赋值操作就会完成.并且再"延迟环境变量扩展"启用后,CMD会用!号来判断这是不是一个变量,没启用,变量用%name%这样的格式判断,启用后就用!name!这样的格式判断,这个符号我们需要注意.
例如
1 | @echo off |
执行结果是
1 | 1 |
再例如
1 | @echo off |
这条命令放在一行,表示它是一条完整的命令,不启用"延迟环境变量扩展",就会出现上面的赋值错误.
改成这样输出就正确了
1 | @echo off |
be yourself, everyone else is already taken.