來源:中國DOS聯盟
關於環境變數延遲擴充,使用set /?可以查看到部分說明,不過考慮到其粗劣的翻譯水平,建議在查看之前,首先chcp 437切換為英文查看原英文說明。鑒於文中已說得十分詳盡,而且有數個程式碼範例,應該不難理解。在此僅略作一些補充。
在許多可見的官方文檔中,均將使用一對百分比符號閉合環境變數以完成對其值的替換行為稱之為“擴充(expansion)”,這其實是一個第一方的概念,是
從命令直譯器的角度進行稱謂的,而從我們使用者的角度來看,則可以將它看作是引用(Reference)、調用(Call)或者擷取(Get)。
而命令直譯器是擴充環境變數的行為大致如下:首先讀取命令列的一條完整語句,在進行一些先期的預先處理之後,命令被解釋執行之前,會對其中用百分比符號閉合的
字串進行匹配,如果在環境空間中找到了與字串相匹配的環境變數,則用其值替換掉原字串及百分比符號本身,如果未得到匹配,則用一個空串替換,這個過程就
是環境變數的“擴充”,它仍然屬於命令列的預先處理範疇。
而一條“完整的語句”,在NT的命令直譯器CMD中被解釋為“for if else”等含有語句塊的語句和用“& | && ||”等串連起來的複合陳述式。
因此,當CMD讀取for語句時,其後用一對圓擴號閉合的所有語句將一同讀取,並完成必要的預先處理工作,這其中就包括環境變數的擴充,所以在for中的
所有語句執行之前,所有的環境變數都已經被替換為for之前所設定的值,從而成為一個字串常量,而不再是變數。無論在for中將那些環境變數如何修改,
真正受到影響的只是環境變數空間,而非for語句內部。
而為了能夠在for語句內部感知環境變數的動態變化,CMD設計了延遲的環境變數擴充特性,也就是說,當CMD讀取了一條完整的語句之後,它不會立即執行變數的擴充行為,而會在某個單條語句執行之前再進行擴充,也就是說,這個擴充行為被“延遲”了。
延遲環境變數擴充特性在CMD中預設是關閉的,開啟它的方法目前有兩個:一是CMD /v:off(此處說法有誤,應為 CMD /v:on——namejm 注),
它會開啟一個新的命令列外殼,在使用exit退出這個外殼之前,擴充特性始終有效,常用於命令列環境中;二是setlocal
EnableDelayedExpansion,它會使環境變數的修改限制到局部空間中,在endlocal之後,擴充特性和之前對環境變數的修改將一同
消失,常用於批處理語句中。