設置本地為延遲擴展。其實也就是:延遲變量,全稱延遲環(huán)境變量擴展, 想進階,變量延遲是必過的一關!所以這一部分希望你能認真看。
為了更好的說明問題,我們先引入一個例子。
例1:
@echo off
set a=4
set a=5echo %a%
pause
結(jié)果:4
解說:為什么是4而不是5呢?在echo之前明明已經(jīng)把變量a的值改成5了?讓我們先了解一下批處理運行命令的機制:批處理讀取命令時是按行讀取的(另外例如for命令等,其后用一對圓括號閉合的所有語句也當作一行),在處理之前要完成必要的預處理工作,這其中就包括對該行命令中的變量賦值。我們現(xiàn)在分析一下例1,批處理在運行到這句“set a=5echo %a%”之前,先把這一句整句讀取并做了預處理——對變量a賦了值,那么%a%當然就是4了?。]有為什么,批處理就是這樣做的。)而為了能夠感知環(huán)境變量的動態(tài)變化,批處理設計了變量延遲。簡單來說,在讀取了一條完整的語句之后,不立即對該行的變量賦值,而會在某個單條語句執(zhí)行之前再進行賦值,也就是說“延遲”了對變量的賦值。那么如何開啟變量延遲呢?變量延遲又需要注意什么呢?
舉個例子說明一下:
例2:
@echo off
setlocal enabledelayedexpansion
set a=4
set a=5echo !a!
pause
結(jié)果:5
解說:由于啟動了變量延遲,得到了正確答案。變量延遲的啟動語句是“setlocal enabledelayedexpansion
”,并且變量要用一對嘆號“!!
”括起來(注意要用英文的嘆號),否則就沒有變量延遲的效果。分析一下例2,首先“setlocal enabledelayedexpansion”開啟變量延遲,然后“set a=4”先給變量a賦值為4,“set a=5echo !a!”這句是給變量a賦值為5并輸出(由于啟動了變量延遲,所以批處理能夠感知到動態(tài)變化,即不是先給該行變量賦值,而是在運行過程中給變量賦值,因此此時a的值就是5了)。再舉一個例子鞏固一下。
例3:
@echo off
setlocal enabledelayedexpansion
for /l %%i in (1,1,5) do ( set a=%%i echo !a! )
pause
結(jié)果:12345
解說:本例開啟了變量延遲并用“!!
”將變量擴起來,因此得到我們預期的結(jié)果。如果不用變量延遲會出現(xiàn)什么結(jié)果呢?結(jié)果是這樣的:ECHO 處于關閉狀態(tài)。ECHO 處于關閉狀態(tài)。ECHO 處于關閉狀態(tài)。ECHO 處于關閉狀態(tài)。ECHO 處于關閉狀態(tài)。即沒有感知到for語句中的動態(tài)變化。
batman的說明
我來簡要說一下吧:
set:設置
local:本地(環(huán)境變量)
enable:能夠
delayed:延遲
expansion:擴展
setlocal enabledelayedexpansion就是擴展本地環(huán)境變量延遲,
比較下面兩段代碼:
@echo off
for /l %%i in (1,1,10) do (
set "str=%%i"
echo %str%
)
pause>nul
@echo offsetlocal enabledelayedexpansion
for /l %%i in (1,1,10) do (
set "str=%%i"
echo !str!
)
pause>nul
第一段代碼只會顯示10行“ECHO 處于關閉狀態(tài)?!?,而第二段代碼則會正確顯示1-10的10行數(shù)字。這是為什么呢?因為在兩段代碼的for循環(huán)前str都是沒有被定義的,而由于第一段代碼沒有開啟變量延遲,所以str值一直是沒有定義,因而顯示出了10行報
錯信息;而第二段代碼開啟了變量延遲,在for循環(huán)中每次賦予str的值被傳遞下去,因而會正確顯示10行數(shù)字,但這里的str變量符必須要寫成!str!,這是沒有道理可講的,只要記住就好了。
setlocal enabledelayedexpansion 是什么意思?
是:設置本地為延遲擴展。其實也就是:延遲變量,全稱"延遲環(huán)境變量擴展",
在cmd執(zhí)行命令前會對腳本進行預處理,其中有一個過程是變量識別過程,在這個過程中,如果有兩個%括起來的如%value%類似這樣的變量,就會對其進行識別,并且查找這個變量對應的值,再而將值替換掉這個變量,這個替換值的過程,就叫做變量擴展,然后再執(zhí)行命令。
在解釋之前,先看幾個例子的區(qū)別:
例一:
set value=kkkkkkk
echo %value%
將這段代碼保存到一個后綴為bat的文本文件中。然后打開dos,進到對應目錄下,執(zhí)行這個文件,結(jié)果如下:
C:\Documents and Settings\Administrator\桌面\ln\temp\bat>set value=kkkkkkk
C:\Documents and Settings\Administrator\桌面\ln\temp\bat>echo kkkkkkk
kkkkkkk
最后一行是結(jié)果,但是在結(jié)果之前,還有兩句,set value=kkkkkkk 和 echo kkkkkkk,但是在語句中,我們并沒有寫echo kkkkkkk的語句,這表明至少在執(zhí)行到echo %value% 這句時,對變量進行的值的替換。這就是變量的擴展。
那么什么是變量的延遲擴展呢?
如果大家知道C++的“靜態(tài)變量”概念,那就應該知道,c++編譯的時候,會對靜態(tài)變量進行值的替換,但這個替換是基于靜態(tài)的前提下,那么進行變量擴展時,也是這樣,但如果出現(xiàn)動態(tài)的情況會怎樣?在cmd執(zhí)行中,發(fā)生動態(tài)的一種情況是在 for語句中進行變量賦值,例如:
例二:
@echo off
for /l %%i in (1,1,3) do (
set k=%%i ::對k進行循環(huán)賦值
echo %k% %%i
)
執(zhí)行這樣的腳本,出現(xiàn)如下結(jié)果:
_1
_2
_3
結(jié)果出現(xiàn)這三句話。_ 表示空格
注:k沒有賦初值,則替換為空。
例三:
@echo off
set k=yyy
for /l %%i in (1,1,3) do (
set k= %%i ::對k進行循環(huán)賦值
echo %k% %%i
)
結(jié)果:
yyy 1
yyy 2
yyy 3
注:k有賦初值,則都替換為yyy。、
實例四:
@echo off
setlocal enabledelayedexpansion
set k= 3
for /l %%i in (1,1,3) do (
set k=%%i
echo %k% %%i
)
結(jié)果:
3 1
3 2
3 3
這里已經(jīng)是用了延遲變量,為什么還會出現(xiàn)這種情況呢?再看實例五:
實例五:
@echo off
setlocal enabledelayedexpansion
set k= 3
for /l %%i in (1,1,3) do (
set k=%%i
echo !k! %%i
)
結(jié)果:
1 1
2 2
3 3
原來在延遲變量擴展中,要使用!來引用變量。
您可能感興趣的文章:- cmd SETLOCAL使用介紹
- dos 環(huán)境變量延遲擴展enabledelayedexpansion詳解