一,什么是延遲環(huán)境變量擴(kuò)展?
延遲變量全稱"延遲環(huán)境變量擴(kuò)展",要理解這個(gè)東西,我們還得先理解一下什么叫變量擴(kuò)展!
CMD在解釋我們的命令的時(shí)候,首先會(huì)讀取一條完整的命令,然后對(duì)其進(jìn)行一些命令格式的匹配操作,看你所輸入的
命令格式是不是符合它的要求.如果我們要在命令中引用一些變量,那么我們?nèi)绾巫孋MD在解釋我們的命令時(shí),能識(shí)別
出這個(gè)變量呢?這時(shí)我們就可以在變量名字兩邊加一個(gè)%號(hào),如%name%.當(dāng)CMD在讀取我們的整條命令進(jìn)行格式匹配的時(shí)
候,就會(huì)發(fā)現(xiàn)name這個(gè)字符兩邊加了%號(hào),就不會(huì)把它當(dāng)作普通字符處理,而是會(huì)把它當(dāng)作一個(gè)變量處理,變量名叫name
然后CMD就會(huì)找到變量名對(duì)應(yīng)的值,用該值替換掉這個(gè)變量名字(name),(如果變量名不存在值,就返回空值).再將這
個(gè)替換好并且匹配的命令執(zhí)行!這個(gè)替換值的過(guò)程,就叫做變量擴(kuò)展,說(shuō)白了就是把變量的名字,用它的值給替換掉后
執(zhí)行!也就是批處理如何識(shí)別一個(gè)變量的過(guò)程.(注意:這里只是變量的擴(kuò)展的意思,不是延遲環(huán)境變量擴(kuò)展,要理解延
遲環(huán)境變量擴(kuò)展,必須先理解什么是變量的擴(kuò)展) 也就是批處理如何識(shí)別一個(gè)變量的過(guò)程.
例1,
@echo off
set var=test
echo %var%
pause
CMD在讀取到echo %var%這句命令后,就會(huì)進(jìn)行匹配操作,它馬上就發(fā)現(xiàn)var字符兩邊有%號(hào),這時(shí)CMD就會(huì)把它當(dāng)作一
個(gè)變量處理,查看這個(gè)var變量名是不是有值,如果有就用該值把變量名var給替換掉,這里我們的var在上一條命令set
var=test中,給var賦值為test,所以CMD會(huì)用test把%var%這個(gè)變量名替換掉,替換后的結(jié)果就為echo test了.這些步
驟都是CMD進(jìn)行匹配操作的步驟,匹配完后,他再執(zhí)行echo test這條語(yǔ)句,這時(shí)我們的CMD中就會(huì)echo出一個(gè)test了.
什么是環(huán)境變量擴(kuò)展知道了,那什么是延遲環(huán)境變量擴(kuò)展呢?
在理解環(huán)境變量擴(kuò)展時(shí),我們知道CMD在解釋命令時(shí),首先會(huì)把一條完整的命令進(jìn)行讀取,然后進(jìn)行匹配操作,匹配時(shí)
它會(huì)把命令里的變量用變量的值給替換掉,然后執(zhí)行這個(gè)替換好的命令.問(wèn)題就出在"一條完整的命令",在BAT中,IF
FOR這樣的命令都可以加括號(hào),將一些命令嵌套在里面執(zhí)行.這樣的話對(duì)于一條可以加擴(kuò)號(hào)嵌其他命令的命令,他的完
整格式就是for %%i in (....)這樣一個(gè)整體.此時(shí),如果我們?nèi)绻诶ㄌ?hào)里面嵌入一些設(shè)置變量值的命令,就會(huì)出現(xiàn)
問(wèn)題了!
例2,
@echo off
for /l %%i in (1,1,5) do (
set var=%%i
echo %var%
)
pause
執(zhí)行后會(huì)顯示5個(gè)空行的錯(cuò)誤提示!為什么?根據(jù)我們上面說(shuō)的知識(shí)來(lái)理解。
通過(guò)這兩個(gè)例子,大家應(yīng)該已經(jīng)理解,如果只有環(huán)境變量擴(kuò)展這個(gè)過(guò)程的話,如果我們?cè)诳梢郧短酌畹拿钪袌?zhí)行
賦值操作時(shí),會(huì)讓我們的BAT出現(xiàn)給變量賦值的問(wèn)題.那么這個(gè)時(shí)候"延遲環(huán)境變量擴(kuò)展",這個(gè)概念就被提出來(lái)了。
在批處理中,我們可以用setloacl enabledelayedexpansion 這個(gè)命令來(lái)啟用"延遲環(huán)境變量擴(kuò)展" ,在我們啟用
了"延遲環(huán)境變量擴(kuò)展"后,當(dāng)CMD在解釋含有嵌套格式的命令時(shí),他會(huì)把嵌套的命令一條一條的先執(zhí)行一次,然后再進(jìn)
行匹配操作,這樣我們的賦值操作就會(huì)完成.并且在"延遲環(huán)境變量擴(kuò)展"啟用后,CMD會(huì)用!號(hào)來(lái)判斷這是不是一個(gè)變量
。如沒(méi)啟用前變量用%name%這樣的格式判斷,啟用后就用!name!這樣的格式判斷了,這個(gè)符號(hào)我們需要注意!
例3,
@echo off
setlocal enabledelayedexpansion
set var=1
for /l %%i in (1,1,5) do (
set /a var =%%i
echo !var!
)
pause
這樣大家應(yīng)該明白什么是延遲環(huán)境變量擴(kuò)展了吧.再來(lái)一個(gè)例子
例4,
@echo off
set var=test echo %test%
pause
這條命令放在一行,表示他是一條完整的命令,不啟用"延遲環(huán)境變量擴(kuò)展",就會(huì)出現(xiàn)上面的賦值錯(cuò)誤!改成下這樣就
OK了:
@echo off
setlocal enabledelayedexpansion
set var=test echo !var!
pause
二,批處理變量延遲詳解
關(guān)于環(huán)境變量延遲擴(kuò)展,使用set /?可以查看到部分說(shuō)明,不過(guò)考慮到其粗劣的翻譯水平,建議在查看之前,首
先chcp 437切換為英文查看原英文說(shuō)明。鑒于文中已說(shuō)得十分詳盡,而且有數(shù)個(gè)代碼示例,應(yīng)該不難理解。在此僅
略作一些補(bǔ)充。
在許多可見(jiàn)的官方文檔中,均將使用一對(duì)百分號(hào)閉合環(huán)境變量以完成對(duì)其值的替換行為稱之為“擴(kuò)展(expansion
)”,這其實(shí)是一個(gè)第一方的概念,是從命令解釋器的角度進(jìn)行稱謂的,而從我們使用者的角度來(lái)看,則可以將它
看作是引用(Reference)、調(diào)用(Call)或者獲?。℅et)。
而命令解釋器是擴(kuò)展環(huán)境變量的行為大致如下:首先讀取命令行的一條完整語(yǔ)句,在進(jìn)行一些先期的預(yù)處理之后
,命令被解釋執(zhí)行之前,會(huì)對(duì)其中用百分號(hào)閉合的字符串進(jìn)行匹配,如果在環(huán)境空間中找到了與字符串相匹配的環(huán)
境變量,則用其值替換掉原字符串及百分號(hào)本身,如果未得到匹配,則用一個(gè)空串替換,這個(gè)過(guò)程就是環(huán)境變量的
“擴(kuò)展”,它仍然屬于命令行的預(yù)處理范疇。
而一條“完整的語(yǔ)句”,在NT的命令解釋器CMD中被解釋為“for if else”等含有語(yǔ)句塊的語(yǔ)句和用“ | ||
”等連接起來(lái)的復(fù)合語(yǔ)句。
因此,當(dāng)CMD讀取for語(yǔ)句時(shí),其后用一對(duì)圓擴(kuò)號(hào)閉合的所有語(yǔ)句將一同讀取,并完成必要的預(yù)處理工作,這其中
就包括環(huán)境變量的擴(kuò)展,所以在for中的所有語(yǔ)句執(zhí)行之前,所有的環(huán)境變量都已經(jīng)被替換為for之前所設(shè)定的值,
從而成為一個(gè)字符串常量,而不再是變量。無(wú)論在for中將那些環(huán)境變量如何修改,真正受到影響的只是環(huán)境變量空
間,而非for語(yǔ)句內(nèi)部。
而為了能夠在for語(yǔ)句內(nèi)部感知環(huán)境變量的動(dòng)態(tài)變化,CMD設(shè)計(jì)了延遲的環(huán)境變量擴(kuò)展特性,也就是說(shuō),當(dāng)CMD讀取
了一條完整的語(yǔ)句之后,它不會(huì)立即執(zhí)行變量的擴(kuò)展行為,而會(huì)在某個(gè)單條語(yǔ)句執(zhí)行之前再進(jìn)行擴(kuò)展,也就是說(shuō),
這個(gè)擴(kuò)展行為被“延遲”了。
延遲環(huán)境變量擴(kuò)展特性在CMD中缺省是關(guān)閉的,開(kāi)啟它的方法目前有兩個(gè):一是CMD /v:off(此處說(shuō)法有誤,應(yīng)為
CMD /v:on——namejm 注),它會(huì)打開(kāi)一個(gè)新的命令行外殼,在使用exit退出這個(gè)外殼之前,擴(kuò)展特性始終有效,
常用于命令行環(huán)境中;二是setlocal EnableDelayedExpansion,它會(huì)使環(huán)境變量的修改限制到局部空間中,在
endlocal之后,擴(kuò)展特性和之前對(duì)環(huán)境變量的修改將一同消失,常用于批處理語(yǔ)句中。
上面是willsort寫的帖子對(duì)于新手來(lái)說(shuō)比較難理解。不過(guò)沒(méi)關(guān)系,我們先分析一個(gè)例子,同樣是引用willsort老
大的。
本例啟用了變量延遲,是個(gè)正確的例子!
例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雙擊執(zhí)行后會(huì)顯示“Will Sort”字符串,下面將講解每個(gè)語(yǔ)句的意思:
1.@echo off setlocal EnableDelayedExpansion
關(guān)閉命令回顯,并啟用變量延遲
2.for /f "tokens=* delims=" %%i in ("Hello world.") do ( )
for命令及其參數(shù)的使用,請(qǐng)大家在論壇里搜索相關(guān)字眼。限于篇幅問(wèn)題,這里不作討論。如果此時(shí)你不明白它的意
思,那么你就當(dāng)它的作用是把字符串“Hello world.”賦值給%%i好了,當(dāng)然這只是權(quán)宜之計(jì),以后一定要學(xué)習(xí)for
的使用!
3.set n=%%i
把%%i的值(即Hello world.)賦予給變量n,這個(gè)大家都知道吧
4.set n=!n:ld.=t!
這里要講講set替換字符的功能了。這個(gè)語(yǔ)句的意思是,先獲取變量n的值(此時(shí)n的值是“Hello world.”),然后
將字符“t”替換字符“l(fā)d.”,然后再將替換后的結(jié)果再次賦值給變量n(此時(shí)n的值變?yōu)椤癏ello wort”)。至于
set替換字符的編寫格式,大家可以在CMD鍵入“set/?”找到“%PATH:str1=str2%”這段有說(shuō)明
5.set n=!n:o w= S!
意思和上句一樣,只是替換和被替換的內(nèi)容不同。它是將“ S”替換“o w”(注意S前面和w前面都有個(gè)空格),其
實(shí)willsort老大是想證明set替換字符是支持句點(diǎn)和空格的(第4句“l(fā)d”后面有個(gè).)。此時(shí)n的值為“Hell Sort”
6.set n=!n:He=Wi!
這句不用說(shuō)了吧,執(zhí)行完這句后n的值為“Will Sort”
7.echo !n!
顯示變量n的值
需要注意的是,一旦啟用了變量延遲,就要用!號(hào)把變量括起來(lái),而不能用%號(hào)。
好了,每句的意思已經(jīng)說(shuō)完了,下面要講本帖真正要討論的變量延遲的問(wèn)題。
這里又要引用Will Sort老大的說(shuō)明:當(dāng)CMD讀取for語(yǔ)句時(shí),其后用一對(duì)圓括號(hào)閉合的所有語(yǔ)句將一同讀取,并完成
必要的預(yù)處理工作,這其中就包括環(huán)境變量的擴(kuò)展,所以在for中的所有語(yǔ)句執(zhí)行之前,所有的環(huán)境變量都已經(jīng)被替
換為for之前所設(shè)定的值,從而成為一個(gè)字符串常量,而不再是變量。
而為了能夠在for語(yǔ)句內(nèi)部感知環(huán)境變量的動(dòng)態(tài)變化,CMD設(shè)計(jì)了延遲的環(huán)境變量擴(kuò)展特性,也就是說(shuō),當(dāng)CMD讀取
了一條完整的語(yǔ)句之后,它不會(huì)立即執(zhí)行變量的擴(kuò)展行為,而會(huì)在某個(gè)單條語(yǔ)句執(zhí)行之前再進(jìn)行擴(kuò)展,也就是說(shuō),這
個(gè)擴(kuò)展行為被“延遲”了。
總的來(lái)說(shuō)是,在沒(méi)有啟用變量延遲的情況下,凡是在括號(hào)內(nèi)(即do里面)的變量,在執(zhí)行for語(yǔ)句之前,就已經(jīng)被
替換成for語(yǔ)句之前其它命令對(duì)該變量所賦予的值。這句話不懂沒(méi)關(guān)系,下面再看一個(gè)例子,看完你就會(huì)明白。
例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
這和前面的例子差不多,只是所有!號(hào)都換成%號(hào),這是個(gè)錯(cuò)誤的例子。因?yàn)樗鼪](méi)有啟用變量延遲,也沒(méi)有使用!
號(hào)把變量括起來(lái)。我們看到它的執(zhí)行結(jié)果是顯示“ECHO 處于關(guān)閉狀態(tài)”。
為什么會(huì)這樣呢?原因是,在沒(méi)有啟用變量延遲的情況下,凡是在括號(hào)內(nèi)(即do里面)的變量,在執(zhí)行for語(yǔ)句之前
,就已經(jīng)被替換成for語(yǔ)句之前其它命令對(duì)該變量所賦予的值。
則是說(shuō)在本例中的以下幾句
set n=%%i
set n=%n:ld.=t%
set n=%n:o w= S%
set n=%n:He=Wi%
echo %n%
第一句能正常執(zhí)行并達(dá)到它的目的,因?yàn)樗皇菃渭兊貙?%i的值賦予給變量n,所以沒(méi)有任何問(wèn)題。其它幾句屬
這樣情況:早在for語(yǔ)句執(zhí)行前,CMD就急不切待地將這幾句里面的所有變量n一同執(zhí)行替換行為,替換為for之前,
其它命令對(duì)n所設(shè)置的值,從而使n變成一個(gè)常量。但在本例中,for語(yǔ)句之前只有@echo off這句,并沒(méi)有其它命令
對(duì)n作過(guò)任何賦值行為,所以在for之前,變量n的值為空值。
即是說(shuō),set n=%n:ld.=t% 這句里面的變量n,在CMD讀取(注意是讀取不是執(zhí)行)完整個(gè)for語(yǔ)句后(這時(shí)還未輪
到set執(zhí)行自己的任務(wù)),就立刻被替換為一個(gè)空值,一個(gè)空值里面沒(méi)有任何東西,所以就不存在一字符替換另一字
符這種說(shuō)法(沒(méi)有東西怎么替換?)。最終到執(zhí)行set n=%n:ld.=t%語(yǔ)句時(shí),它只是獲取一個(gè)空值,再給變量n賦予
空值而已。其它幾句也是一樣原理。
所以,最后echo %n%的時(shí)候變量n還是個(gè)空值,而echo命令沒(méi)有東西可以顯示,就只有顯示“ECHO 處于關(guān)閉狀態(tài)
”這句來(lái)說(shuō)明自己的狀態(tài)
通過(guò)這個(gè)例子的說(shuō)明,相信大家已經(jīng)知道變量延遲的作用吧!我們?cè)倩仡^來(lái)看看例1。
啟用變量延遲后,在執(zhí)行
set n=!n:ld.=t!
set n=!n:o w= S!
set n=!n:He=Wi!
echo !n!
這些語(yǔ)句前,它們里面的變量n不會(huì)馬上被CMD替換(啟用延遲后,CMD變得有耐性啦^_^),而未被替換的話,那么n
就還是變量,而不是常量。等到執(zhí)行set n=!n:ld.=t!等這幾句時(shí),變量n才被替換。這樣每個(gè)set命令都能感知變量
n的任何變化,從而作出正確的替換行為。這就是變量延遲啦!
不要以為只有for才要用變量延遲,下面這個(gè)例子同樣需要
例3,這是個(gè)錯(cuò)誤的例子
@echo off
set mm=girlecho %mm%
pause
執(zhí)行后依然顯示“ECHO 處于關(guān)閉狀態(tài)”。
原因是沒(méi)有啟用延遲,而且在set mm=girlecho %mm%語(yǔ)句前沒(méi)有其它命令對(duì)mm進(jìn)行賦值。這時(shí)當(dāng)CMD執(zhí)行set
mm=girlecho %mm%語(yǔ)句前,就已經(jīng)急不切待地把變量mm的值替換了,而又因?yàn)榍懊鏇](méi)給mm賦值,所以mm被替換為空
值,變成常量。等到echo命令執(zhí)行時(shí),它其實(shí)是echo一個(gè)不會(huì)變化的常量,本例中即是空值。
有人會(huì)問(wèn),echo前面不是給mm賦值了嗎?
這個(gè)就要關(guān)系到CMD解釋命令的步驟,大家可以參詳本帖開(kāi)頭willsort的帖子。
總的來(lái)說(shuō)是,如果不啟用變量延遲,在本例中,echo是不會(huì)理會(huì)也不會(huì)知道,它前面(指同一行語(yǔ)句)是否有其
它命令給mm賦值。它只會(huì)從set mm=girlecho %mm%這句以上的語(yǔ)句中獲取它所要顯示的變量的內(nèi)容,也就是說(shuō),上
一行或上幾行的命令將mm設(shè)置成什么值,echo命令就顯示什么值。
大家這樣做就明白了:
@echo off
set mm=boy
set mm=girlecho %mm%
pause
看看顯示什么結(jié)果就知道了!
這樣編寫例3才正確:
@echo offsetlocal EnableDelayedExpansion
set mm=girlecho !mm!
pause
開(kāi)啟了變量延遲,變量擴(kuò)展(替換)的行為就推遲到echo命令執(zhí)行時(shí),這時(shí)echo能感知它前面的命令(本例的set)
對(duì)變量mm做了什么“壞事”,從而作出正確的判斷并執(zhí)行
三,批處理延遲變量(通俗解釋)
變量延遲 setlocal EnableDelayedExpansion
一個(gè)讓大多數(shù)新手頭痛的問(wèn)題,網(wǎng)上教程雖多,但多半都是看不懂的,里面的專業(yè)術(shù)語(yǔ)太多。
以 cn-dos 聯(lián)盟的willsort的這篇教程為例,(個(gè)人認(rèn)為是解釋的極具權(quán)威和專業(yè)的)
但可能就是因?yàn)閷I(yè),所以才看不懂,因?yàn)閷W(xué)cmd批處理的并不一定都是學(xué)計(jì)算機(jī)專業(yè)的。這個(gè)鬼東西確實(shí)不太好
理解,在下也是摸爬滾打多時(shí),總結(jié)出一點(diǎn)點(diǎn)經(jīng)驗(yàn),現(xiàn)用通俗的方法解釋出來(lái),希望能給新手些幫助,老鳥(niǎo)們見(jiàn)笑
了,若有不對(duì)的地方,歡迎指出。
言歸正傳
在什么時(shí)候需要延遲變量,和該如何引用延遲變量,我想這才是大多數(shù)新手迫切想要知道的問(wèn)題。
耐心看完下面的內(nèi)容,我想對(duì)你應(yīng)該是有幫助的。
要想了解延遲變量,首先你要明白什么是“復(fù)合語(yǔ)句”好像又來(lái)了個(gè)“專業(yè)”名詞,別急,這個(gè)超好理解。所謂
“復(fù)合語(yǔ)句”就是指一對(duì)()里的所有命令。比如for的do后面
如:
for /f "delims=" %%i in (a.txt) do (
set var=%%i
echo %%i
set num=%%i
)
這里do后面的三句命令,在一對(duì)()里面,這就叫“復(fù)合語(yǔ)句”,當(dāng)然不止for 還有if 等等。。。
如:
if "%var%"=="abc" (
echo ok
set lis=123
)
反正就是凡是()里的所有命令,就叫“復(fù)合語(yǔ)句”
另外:這也是復(fù)合語(yǔ)句 set abc=123echo %abc% 沒(méi)錯(cuò),通過(guò)管道命令連接起來(lái)的命令,也是復(fù)合語(yǔ)句。
好,了解了復(fù)合語(yǔ)句,現(xiàn)在開(kāi)始講延遲變量,也就說(shuō),在復(fù)合語(yǔ)句中才要使用延遲變量。
我們先不去理解什么叫“變量的擴(kuò)展”這玩意叫法太專業(yè),我到現(xiàn)在都不太明白,
我們只要知道在什么時(shí)候需要使用延遲變量,如何才能正確提取到我們需要的變量就可以了,這才是我們的目的。
cmd在處理“復(fù)合語(yǔ)句”的時(shí)候,如果“復(fù)合語(yǔ)句”中用到了變量,會(huì)把變量的值當(dāng)作復(fù)合語(yǔ)句之前變量的值來(lái)引用
。如果在此之前變量沒(méi)有被賦值,就把它當(dāng)成空值。
例1,
@echo off
for /l %%i in (1 1 10) do (
set var=%%i
echo %var%
)
Pause
運(yùn)行上面的代碼,顯示什么?顯示10個(gè)echo處于關(guān)閉狀態(tài)。按照邏輯,var的值應(yīng)該依次是 1、2、3........10 才
對(duì)?。?/p>
這就是因?yàn)闆](méi)有開(kāi)啟 延遲變量 的緣故,cmd把var的值當(dāng)作復(fù)合語(yǔ)句之前的值來(lái)引用,
而在本例中,復(fù)合語(yǔ)句之前并沒(méi)有給var定義,所以var的值是空的,所以會(huì)顯示10個(gè)echo處于關(guān)閉狀態(tài)。
例2,
@echo off
set var=abc
for /l %%i in (1 1 10) do (
set var=%%i
echo %var%
)
Pause
運(yùn)行上面的代碼,會(huì)顯示什么,大家應(yīng)該知道了吧?
例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
運(yùn)行上面的代碼后,復(fù)合語(yǔ)句中所賦的值全部顯示出來(lái)了,這說(shuō)明什么呢?
說(shuō)明,在復(fù)合語(yǔ)句中,并不是沒(méi)有給變量賦值,只是你若沒(méi)有開(kāi)啟延遲變量,你就沒(méi)法在復(fù)合語(yǔ)句中提取到它,要
等復(fù)合語(yǔ)句運(yùn)行完畢后,才能提取到。
變量的表示方法:兩種: 1、%var% 2、!var!
第一種表示方法,大家都知道,第二種就是引用 延遲的變量。
在開(kāi)啟了延遲變量的情況下,如果在復(fù)合語(yǔ)句之外,用哪種方法表示都可以。但是你若要在復(fù)合語(yǔ)句中引用復(fù)合語(yǔ)
句即時(shí)得到的變量,就要用第二種方法。看例子
例4,
@echo off
setlocal EnableDelayedExpansion
set var=abc
for /l %%i in (1 1 10) do (
set var=%%i
echo %var%
echo !var!
)
Pause
注意:例子中有兩個(gè)echo 一個(gè)是顯示 %var% 一個(gè)是顯示 !var!
結(jié)果很明白了,%var% 顯示的結(jié)果是復(fù)合語(yǔ)句之前變量var的值,而 !var! 顯示的就是復(fù)合語(yǔ)句中即時(shí)得到的值。
例5,
@echo off
setlocal EnableDelayedExpansion
for /l %%i in (1 1 5) do (
set var%%i=%%i
)
echo %var1% %var2% %var3% %var4% %var5%
echo !var1! !var2! !var3! !var4! !var5!
pause
這個(gè)例子說(shuō)明什么,不用再解釋了吧?
說(shuō)明在開(kāi)啟了延遲變量的情況下,且在復(fù)合語(yǔ)句之外,用兩種方法都可以表示變量。就說(shuō)到這吧。以上的解釋,完
全是出于個(gè)人的理解,也是為方便非專業(yè)人士理解,解釋肯定有錯(cuò)誤的地方、就象學(xué)習(xí)英語(yǔ)時(shí),為方便記憶,用漢
字的讀音來(lái)作解釋一樣。呵呵,是一種“偏門”各位新手千萬(wàn)不要把以上所說(shuō)的當(dāng)成是“真理”,否則就變成是“
誤人”了。
四,什么時(shí)候使用延遲變量?如何使用?
什么時(shí)候使用延遲變量?如何使用?這些一直是使新手困惑的地方,那到底是怎么樣的呢?那請(qǐng)看下面的例子,
我們將一步步引導(dǎo)大家。
例1,
@echo off
set /a num=0
for /l %%i in (1 1 3) do (
Rem ================================
set /a num =1
Rem 原意是變量num的值每次都加1
Rem ================================
echo %num%
)
pause>nul
先猜猜看,運(yùn)行之后的結(jié)果是什么呢?你是不是認(rèn)為它會(huì)顯示:1 2 3 呢?我想大部分人會(huì)這么認(rèn)為。你再將以
上代碼保存為批處理文件,運(yùn)行,看看結(jié)果。
你會(huì)看到,顯示的結(jié)果并不是意料中的 1 2 3 而是 0 0 0,這個(gè)是為什么呢?
原來(lái)這個(gè)是因?yàn)椋幚碓谔幚韋or 或者if 語(yǔ)句中的變量時(shí),先要進(jìn)行預(yù)處理,把其中的用%%括起來(lái)的變量,先
替換為語(yǔ)句之前的變量(如上面的代碼,for語(yǔ)句中的%num%早就被替換為語(yǔ)句前的 值:0),所以,for語(yǔ)句運(yùn)行時(shí)
,雖然已經(jīng)給變量加了1,但是,值卻不變(因?yàn)閑cho %num%中的%num%早已被替換為:0了)。
那么,要實(shí)現(xiàn)(for或者if)語(yǔ)句中的變量實(shí)時(shí)的變化(如這里,我就要將1 2 3 顯示出來(lái))要怎么辦呢?那就要起
用延遲變量,先在批處理中申明:setlocal enabledelayedexpansion 然后,將語(yǔ)句:echo %num%改成!num!(也就
是將“%”改成“!”),這樣就可以達(dá)到效果了,演示代碼:
例2,
@echo off
Rem ''''///////下面先申明起用延遲變量/////////////
setlocal enabledelayedexpansion
set /a num=0
for /l %%i in (1 1 3) do (
Rem ================================
set /a num =1
Rem 變量num的值每次都加1
Rem ================================
Rem '''''''//////////////////下面的變量不能再用"%"括起來(lái),而應(yīng)該用"!"http:////////////
echo !num!
)
pause>nul
歸納總結(jié):
1、為什么要用延遲變量?
讓if語(yǔ)句和for語(yǔ)句中的變量實(shí)時(shí)變化;
2、什么時(shí)候用延遲變量?
一般是用在 for 語(yǔ)句和 if 語(yǔ)句中;
3、怎么用延遲變量?
先在批處理中申明起用延遲變量:setlocal enabledelayedexpansion
然后將 for 語(yǔ)句、if語(yǔ)句中的變量用兩個(gè)"!"括起來(lái)即可
4、其實(shí)在使用變量嵌套變量也可以使用變量延遲的。
例3,
@echo off
set a=1
set b1=10
echo %b%a%%
pause
執(zhí)行顯示,得到 %b1%
其實(shí)我想得到的是 賦予b1的值,即 10 那么如何實(shí)現(xiàn)呢?將上例修改如下,
例4,
@echo off
set a=1set b1=10
call,echo %%b%a%%%
pause>nul
call 這里實(shí)際是對(duì)命令行進(jìn)行重新組織擴(kuò)展,先擴(kuò)展%%b%a%%%里面的%a%,使%a%變成a的值1,再用cal來(lái)擴(kuò)展%b1%
。
也可以用變量延遲來(lái)實(shí)現(xiàn),方法如下:
例5,
@echo off
set /a a=1,b1=10
Setlocal EnableDelayedExpansion
echo:!b%a%! ...
pause
call 在這里的用法實(shí)際是變量延遲的一種快捷方式,變量延遲一般用在for的循環(huán)體里面。
call,%%b%a%%% 這里的逗號(hào)實(shí)際是一個(gè)分隔符,和空格一樣,還有很多分隔符可用,比如上例中的 echo:!b%a%! ,
當(dāng)然并不是所有的命令都可以這樣用,看情況而定……
例6,
@echo offsetlocal enabledelayedexpansion
set a=1000
set b=dd
set a%b%=9000
set c=!a%b%!
echo %c%
pause
執(zhí)行一下,看看顯示的將是什么?為什么是這樣?相信通過(guò)例4,例5你也能分析得出來(lái)吧?
您可能感興趣的文章:- 批處理中setlocal enabledelayedexpansion的作用詳細(xì)整理
- cmd SETLOCAL使用介紹