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