天天看點

由batch 指令setlocal enabledelayedexpansion引發的

預告:先來一段長長的唠叨!

作為一名比較能折騰的初級程式員,對一切都充滿了好奇心,強迫症是個比較流行的詞,我想我也應該是中毒份子吧。

由batch 指令setlocal enabledelayedexpansion引發的

左面寫程式,右面看文檔,爽多了!

---------------------------------------------很高興你能看到華麗的分割線,下面進入正題--------------------------------------------------------------------------------------------------------------------------

在電腦變快之後,裝上了vb,然後想裝個綠色版qq,網上jayxon的應該是最普及的,他這裡面有個bat檔案,以前也沒想着去打開看看,今天突發奇想打開看了看,發現是個很神奇(其實是micorsoft比較笨吧)的代碼:

網上發現這叫延遲環境變量擴充,很奇怪的名字,這是什麼回事呢,google一番後發現是這麼回事:

batch檔案在執行時,解釋器會把先把一整條指令讀入,然後分析文法是否正确,這在單句是沒有任何問題的,但是bat檔案中的if、for等這些符合語句(符合也算一個語句)就有問題了,下面我一一以代碼示範之。下面的代碼寫在c:\hello.bat檔案中,讀者可以copy自行實踐之。

上面是很簡單的單句指派情況,程式能夠程式正确輸出helloworld

下面看看如果是if語句會怎麼樣呢?

這時程式會輸出什麼呢?不了解batch檔案的人肯定說是helloubuntu了,但是事實卻還是helloworld,這是為什麼呢?

現在我請你換下身份,以batch解釋器而不是程式員的思路來看這個腳本到底是怎麼執行的:

1.首先,解釋器看到if後知道這條語句是個符合語句,那麼他會讀取一個完整句子後在進行後面的文法驗證、執行(讀整個句子時并不執行)等操作

2.讀完整個句子後,解釋器會進行一項變量擴充(也就是我們熟知的變量替換)的工作,batch特有的文法是兩個%之間的變量(上面的%foo%就是)會被替換

3.完成替換工作後,解釋器開始執行這個整句。

在上面3個過程後,解釋器看到的是這樣的代碼:

是以,這麼一看,輸出helloworld一點也不奇怪了。

為了加深大家的了解,我在給一個for的例子

這會輸入什麼呢,看看結果

由batch 指令setlocal enabledelayedexpansion引發的

為什麼會這樣呢?讀者可以試着吧編譯器看到的結果自己寫出來,其實也很簡單

就是這樣的嘛,那麼為什麼會是上面的資訊呢,這裡你需要了解echo指令的用法,如果你隻輸入一個echo,後面不跟任何參數,那麼将輸出echo的狀态

由batch 指令setlocal enabledelayedexpansion引發的

通過echo的幫助文檔我們可以很清楚的了解,同時對于batch能夠識别的指令都能夠用類似的文法獲得

因為我們第一行的@echo off将echo的狀态給關閉了,是以輸入了如上的資訊。

到現在位置我們已經知道了batch解釋器在解釋符合語句時的問題了,那麼微軟時如何解決的呢,其實我們自己想想也很好相出辦法解決,你一行行的讀入不就行了嘛,幹嘛非要讀入符合語句的整句。其實微軟也是這麼做的,這就是本文标題指令的由來了,不過這是為了要用!變量名!的形式來引用了。 

我們這次把上面的兩個例子加上setlocal enabledelayedexpansion再試試看:

首先是if的情況

由batch 指令setlocal enabledelayedexpansion引發的

for的那個例子:

由batch 指令setlocal enabledelayedexpansion引發的

結果和我們預想的一樣了。