Windows批處理中的變數和值

公子奇的博客發表於2024-09-02

透過前面對批處理的介紹,我們已經準備好了開始編碼,今天我們將討論變數、值和批處理的set命令,該命令將一個值賦值給一個變數。如果您用過其他計算機語言做過開發,這些可能顯得微不足道,但是批處理有一些獨特的特性需要我們去注意。

透過本文,您將學習如何在控制檯中顯示變數的值,以確認它已被正確設定。此外,我將介紹命令分隔符,它允許您在一行中輸入多個命令。我還將向您展示如何建立註釋和設定儲存在計算機上的變數,這些變數即使在bat檔案關閉後也仍然可用。最後,您將學習如何在命令提示符下訪問任何批處理命令的文件,這對於使用bat檔案的任何人來說都是一項有用的技能。

設定和解析變數

變數是一個命名欄位,它在記憶體中定義了一個位置,該位置儲存了供以後使用的值。大多數計算機語言允許並且通常要求在賦值之前將變數定義為特定的資料型別,常用的是字串或數字。批處理通常不用設定具體的資料型別;變數在第一次被“設定”為一個值時就存在了,這個值可以包含字母、數字和其他字元。然後由編碼人員決定是否將它們視為特定的資料型別。本文的重點是為變數賦值這一看似簡單的任務。

考慮一個變數的例子,一個程式設計師可能有一個包含他們情緒狀態的欄位。變數被定義為或命名為myMood,其中兩個可能的值是happysad。要將變數設定為happy,這裡可以使用set命令:

> set myMood=happy

執行完這個命令後,myMood變數包含了happy值。

下面的命令將刪除先前的值並用另一個值替換它:

> set myMood=nonplussed

但是如何確定這個或其他變數的值呢?在批處理中,顯示變數值的行為被稱為解析變數,通常在變數兩邊加上百分號來完成。也就是說,在前面的set命令執行後,%myMood%將解析為nonplsed。現在,為了實際看到解析變數的結果,我們需要了解變數之外的知識。

顯示變數的值

在這裡我們將學習如何在計算機螢幕上快速顯示變數的解析值,但這種技術的用途遠不止於此。我們將在以後的文章中來演示批處理的許多其他特性,例如使用它作為測試技術,這對任何批處理程式都是有用的。

寫入控制檯

要在螢幕上顯示變數的內容,我們需要兩個額外的命令:echo和pause。下面我們建立一個簡單的bat檔案。在計算機上開啟一個新資料夾,比如D:\Batch\,並在其中建立一個名為Mood.bat的bat檔案,程式碼如下:

set myMood=happy
echo My mood is %myMood%.
pause

這裡bat檔案Mood.bat顯示一個已解析的變數。

如果雙擊或開啟Mood.bat, bat檔案將被執行,並出現一個帶有白色文字的黑色視窗。這個視窗就是DOS視窗或者叫控制檯。

前面我們已經瞭解了set命令。在這裡,echo命令是將語句的其餘部分(不包括echo本身及後面的空格)寫到控制檯。顯示文字My mood is和尾隨空格,後跟myMood的內容或值(即文字happy)和最後的句號。pause命令使控制檯保持開啟狀態。沒有它,視窗將會一閃而過,我們什麼效果都看不到(即視窗開啟後立即關閉了)。

開啟後控制檯具體顯示內容如下:

D:\Batch>set myMood=happy

D:\Batch>echo My mood is happy.
My mood is happy.

D:\Batch>pause
請按任意鍵繼續. . .

每個命令前面都有當前目錄D:\Batch\,後面跟著一個大於號(>)作為分隔符。

第一行顯示set命令的執行,第二行顯示echo命令的執行。第三行是執行該echo的結果,即控制檯輸出。您可以看出它不是命令,因為前面沒有文字D:\Batch>。這裡需要注意的是%myMood%解析為文字happy了。pause命令也會產生輸出,為文字請按任意鍵繼續…,如控制檯所示,執行將暫停,直到按下任何鍵,此時bat檔案將結束,控制檯將關閉。另外,請注意set命令不產生任何輸出,因為它只是設定一個變數的值。

清除控制檯

寫入控制檯的內容的一個問題是,命令與echo和pause命令的期望輸出交織在一起。這裡我們來看看一個快速清理的方法。在Mood.bat bat檔案的頂部新增@echo off後再次執行:

@echo off
set myMood=happy
echo My mood is %myMood%.
pause

這個echo off命令抑制的不是後續命令的實際輸出,而是顯示正在執行的每個命令的行—即以當前目錄為字首的行。此外,在echo命令前加上@符號(@)會阻止它自己的執行被寫入控制檯。

與前面相比,當執行修改後的bat檔案時,控制檯顯示更加清晰:

My mood is happy.
請按任意鍵繼續. . .

現在我們可以很容易地演示如何將myMood變數初始化為gloomy,然後將其重置為cheerful:

@echo off
set myMood=gloomy
echo My mood is %myMood%.
set myMood=cheerful
echo Now my mood is %myMood%.
pause

結果顯示同一個變數在兩個不同的時間被解析為兩個不同的值:

My mood is gloomy.
Now my mood is cheerful.
請按任意鍵繼續. . .

隨著我們的bat檔案變得越來越複雜,echo命令可以將輸出傳送到控制檯以外的地方。

set命令的特性

對於大多數程式語言來說,設定變數通常是一個簡單的事情,但批處理與大多數程式語言不同。所有批處理程式設計師都需要了解set命令的以下特性,以避免將來某種程度的痛苦。

大小寫敏感

仔細檢查以下兩個命令。它們看起來有點不同,但功能相同:

SET myMood=whimsical
set MYMOOD=whimsical

批處理命令和變數不區分大小寫。在這裡,set命令在一個命令中是大寫的,在另一個命令中是小寫的,但是直譯器將它們視為相同的。您也可以在不改變功能的情況下使用Set。為了更好地衡量,sET和sET也以相同的方式工作。同樣,您可以互換使用myMood、MYMOOD和mymood變數。但是,該值是按照鍵入的方式儲存的,因此它是區分大小寫的。如果變數被設定為WHIMSICAL,將被解析為WHIMSICAL;同樣,如果它被設定為Whimsical,它將被解析為Whimsical。

這完全是風格和個人喜好的問題。我發現許多bat檔案有太多的內容大寫。大寫是為了突出某些東西,但當所有東西都閃爍著霓虹燈時,什麼都不突出。大多數批處理程式設計師將命令名稱中的所有字母大寫,但在我們這裡,我只使用小寫字元來表示所有批處理命令。另外,我也非常喜歡駝峰式變數。

注意:

駝峰大小寫文字很容易閱讀,即使它包含多個單詞,沒有空格或其他字元分隔。駝峰大小寫文字的第一個字母可以是大寫或小寫。但是要符合駝峰大小寫,所有後續單詞的第一個字母必須大寫,其餘單詞必須小寫。MyMood就是一個例子(也稱為Pascal或上駝峰)。相應的myMood也是一個很好的例子(也稱為單峰或下駱駝)。

有效的變數字元

大多數程式語言對於變數名中允許的字元列表都有嚴格的規則。通常情況下,數字和26個字母(大寫和小寫)是允許的,只有幾個特殊字元可以使用。但是批處理的獨特之處在於,鍵盤上的幾乎每個字元都是有效的變數名字元,但是我們應該儘量避免在變數名中使用數字作為第一個字元。

一些字元是非法的,因為它們在批處理中有特定的用途;例如,波浪號(~)、&號(&)、百分號(%)和小於號(<)和大於號(>)都是保留字元,但是其他幾個字元會讓不熟悉批處理的程式設計師感到驚訝。下面三個變數在批處理中也是合法的:

set ;=semicolon
set @=at
set #=hashtag

echo %;% %@% %#%

pause

甚至下面的怪異變數也儲存了文字,這實際上是在帶有美元符號、點和不匹配括號的變數中工作的:

set var$with.odd[chars}=This actually works

這個變數名演示了各種怪異的變數都是可能的,但是很難閱讀,不推薦使用。

然而,在變數名中明智地使用這些字元可能是一個方便的工具。例如,一組相關變數可能都有一個開頭或結尾下劃線作為這種關聯;number可以縮寫為#,比NBR更簡潔,比no更清晰。在後面,我將使用這個有趣的特性來構建陣列和雜湊表,這些陣列和雜湊表的名稱包含括號。

賦值運算子周圍的空格

以下是大多數熟悉其他語言的批處理程式新手都會犯的典型錯誤。仔細檢查下面的set命令。

set X = Hello

echo The value of X is "%X%".

如果您期望echo命令的結果為

The value of X is "Hello".

這是一個可以理解的錯誤,但畢竟是一個錯誤。結果是這樣的:

The value of X is "".

空引號表示X沒有設定或設定為null,即什麼都沒有,甚至沒有空格。

注意:

在上一篇文章中,我們提到在命令提示符中,與bat檔案相比,語法和輸出可能有所不同,這就是一個很好的例子。在命令提示符下輸入的相同程式碼顯示結果將不同:

The value of X is "%X%".

在後面程式碼的執行過程中若存在什麼異常,我們可以嘗試著將程式碼放入到bat檔案中執行試試。

現在上面程式碼中的set命令並不是那麼複雜,它顯然想將X設定為文字Hello?此外,它看起來很像其他現代的程式語言中的賦值命令,可以按需要執行賦值。

這是我們第一次出現問題,這個問題的關鍵是等號前面的空格。變數名以set命令後的第一個非空格字元開始,以賦值運算子或等號之前的字元結束——無論該字元是什麼。因此,這裡設定的變數長度為兩個字元,X後跟空格:

set X = Hello

echo The value of X-space is "%X %"

解析帶有尾隨空格的變數現在會顯示它的值,其中包含一個前導空格:

The value of X-space is " Hello".

更容易犯的錯誤是在值後面的行末尾無意中新增一兩個空格。因為僅僅在編輯器中檢視文字並不明顯,所以很容易忽略它。(在 Notepad++中, 檢視--->顯示符號--->顯示空格與製表符)它將在每行的行尾將空格以點表示,將Tab鍵以箭頭顯示。

命令分隔符

&是一種特殊字元,用作命令分隔符;它不像簡單的文字那樣被處理。例如,您可以將多行程式碼串成一行,每個命令用&字元分隔:

set ;=semicolon& set @=at& set #=hashtag

這在功能上等同於三個不同行的三個命令。

有時,這種技術對於合併簡單和類似的命令很有用,但是過度使用它會使程式碼難以閱讀。但是,我發現了命令分隔符的兩種非常方便的用法。

向命令追加註釋

命令分隔符的一種用途是在行尾新增文字,以便將其視為註釋。rem命令根據它後面的文字建立註釋。通常,我們將rem命令作為註釋放在一些程式碼前面的行上,但我們也可以使用命令分隔符將其附加到特定命令上。例如,下面兩行執行相同的邏輯:

set myMood=reflective
set myMood=reflective& rem This is a thoughtful and contemplative mood.

然而,第二行為閱讀程式碼的人提供了更多的資訊。

終止命令

命令分隔符的第二個用途是明確地終止命令,以便程式設計師可以清楚地描述是否存在任何尾隨空格。下面的命令是否將變數設定為null、一個空格或多個空格?

set myMood=

正如所寫的那樣,這是不可能的(除非您讓編輯器將空格顯示為可見字元)。

如果您沒有閱讀前面的內容,下面的命令可能會將變數設定為&符號:

set myMood=&

但是這個命令明確地告訴讀者,變數被設定為null,因為語句被緊接在相等運算子之後的&號終止。

同樣地,當程式設計師可能希望變數具有一定的長度時,也存在這樣的例項。下面的命令將變數設定為一個10位元組的左對齊值,其中包含文字和三個空格:

set myMood=pensive    &

如果沒有&符號,就很難確定文字後面有多少空格(如果有的話)。從技術上講,&號並沒有分隔兩個命令,但它確實終止了一個命令。

顯示變數資訊

set命令還有一個更有趣的用法。當不使用等號時,它會寫出變數的值,所以如果myMood變數已經定義了,你可以在bat檔案中輸入這個命令:

set myMood

寫入控制檯的結果輸出可能如下所示:

myMood=hopeful

如果在set命令後只輸入變數名的一部分,則將顯示以該文字開頭的所有變數。因此,下面的命令可能會輸出多於myMood變數的值:

set myM

也許,只是也許,它可能輸出如下:

Mymar=A Genus of Fairyflies
myMood=hopeful

這樣的變數不太可能被設定,但是如果它確實存在,並且如果這是機器上以mym開頭的僅有的兩個變數,那麼輸出應該是這樣的。注意,該命令查詢所有變數,而不考慮大小寫。還要注意包含嵌入空格的變數值的示例。

在瞭解了該技術對完整變數名和部分變數名的處理後,我們可以將其擴充套件到完全沒有變數名:

set

這個不帶引數的命令生成所有可用變數的列表,這些變數是在bat檔案啟動時載入的,以及來自bat檔案本身的對列表的任何新增和修改。

設定變數持久化

set命令本質上是臨時的。它在特定批處理流中定義變數,直到變數被重新賦值或指令碼終止,此時透過set命令設定的所有變數都消失。但是有時我們希望變數可以被計算機上的其他程序或其他bat檔案訪問,並且在原始bat檔案終止後很長一段時間內,甚至在計算機關閉並重新啟動之後。我們想要的是一個極限集合命令,我們使用setx命令就是為了這個目的。

假設set和setx命令的語法是相同的,這是合乎邏輯的。除了一個變數、一個等號和一個值,但令人費解的是事實並非如此。setx命令不呼叫等號。相反,變數名和值由一個或多個空格分隔,如下所示:

setx myMood puzzled

在討論set命令時,很明顯變數名和值確實可以包含空格。當在設定變數的命令中使用空格作為分隔符時,顯然會出現一種問題。但是將變數名和/或值用雙引號括起來可以快速解決問題。下面的命令建立了一個有兩個單詞名稱的變數,並給它賦了一個兩個單詞的值:

setx "my mood"  "cautiously optimistic"

為了測試這一點,首先在一個bat檔案中執行前面的語句,然後在另一個bat檔案中甚至在命令提示符中執行以下命令:

set my m

要檢視效果,必須在setx命令完成後啟動第二個bat檔案或開啟命令提示符,因為直譯器在會話開始時使用計算機現有的變數載入會話。

將顯示所有以my m開頭的變數(不區分大小寫,包括嵌入的空格),包括變數my mood。除非這個變數被其他程序重新賦值,比如將來的setx命令,否則只要計算機是可操作的,它就會以這個值存在。

setx命令是一個很好的工具,可以幫助開發編譯後的程式碼。當開發的特定程式最終在生產環境中執行時,它顯然會在具有自己環境變數的不同機器上執行。當執行程式時,一些ide有一個很好的機制來模擬這些環境變數和檔案聯結器的設定;令人遺憾的是,其他人沒有這些環境。一個很好的解決方案是啟動之前在開發機器上設定所有需要的值。

對於用特定語言開發的每個程式,我將建立一個包含一系列setx命令的bat檔案,每個命令對應需要持久設定的變數。在執行了bat檔案之後,我可以讓程式執行起來,它將找到我期望它在稍後的生產環境中執行時找到的所有環境變數。如果我想執行一個不同的程式,我可以先執行與它相關的bat檔案,這既快速又容易,如果我覺得需要在完成後將一些變數恢復到之前的狀態,我也可以為此建立一個bat檔案。

命令列幫助

我們介紹的最後一個批處理命令是記錄我已經討論過的命令以及所有其他命令的命令。help命令接受另一個命令作為其引數,並返回關於該命令的大量資訊,首先是對其函式及其一般語法的簡要描述。

我將用set命令來演示,因為它是本文的核心。要呼叫幫助命令,請在命令提示符中輸入它(在Windows開始選單中輸入CMD並按enter)。然後,要接收關於set命令的更多詳細資訊,請輸入以下命令:

help set

直譯器產生了太多關於set命令的資訊,下面顯示部分資訊:

顯示、設定或刪除 cmd.exe 環境變數。

SET [variable=[string]]

  variable  指定環境變數名。
  string    指定要指派給變數的一系列字串。

要顯示當前環境變數,鍵入不帶引數的 SET。

如果命令擴充套件被啟用,SET 會如下改變:

可僅用一個變數啟用 SET 命令,等號或值不顯示所有字首匹配
SET 命令已使用的名稱的所有變數的值。例如:

    SET P

會顯示所有以字母 P 打頭的變數

如果在當前環境中找不到該變數名稱,SET 命令將把 ERRORLEVEL
設定成 1。

SET 命令不允許變數名含有等號。

在 SET 命令中新增了兩個新命令列開關:

    SET /A expression
    SET /P variable=[promptString]

該命令的簡要描述之後緊接著是它的通用語法,它顯然是從命令名稱本身開始的。方括號內的所有文字都是可選的。文字週圍的方括號[variable=[string]]表明該命令可以在有或沒有文字的情況下工作。請記住,不帶引數的set命令返回所有可用變數的列表。巢狀的方括號更進一步,表明string也是可選的——也就是說,變數可以被設定為什麼都沒有。

某些命令的幫助提供了命令的使用示例,以及附加說明和可用選項列表。選項是分配給命令的設定或調整,用於開啟或關閉一些附加功能。它們也被稱為開關;事實上,help命令交替使用這兩個術語。為了保持一致性,我將只使用更流行的術語選項,但是如果有人提到批處理命令開關,他們指的是一個選項。

選項通常是用正斜槓加一個字母來定義的,但你最終會遇到一些更復雜的選項。在命令提示符中向下滾動,顯示set命令的幫助,以檢視兩個有趣且有用的選項。/A選項允許命令執行算術運算。/P或prompt選項用於設定使用者輸入資料的變數。

在前面的文章中,可能是你的第一個bat檔案包含一個命令來複制一些檔案。這裡我們不會詳細介紹xcopy命令,但在前面中,它使用了三個選項(/F、/S和/Y)。它們到底能做什麼還不重要。重要的是,它們可以開啟或關閉某些功能,並使用幫助命令對它們進行記錄。

有些命令有很多選項,有些只有幾個選項,還有一些沒有選項。在介紹命令時,我將詳細介紹我認為重要和有用的選項,但您可能希望使用help命令來查詢更完整的列表。但是,在help命令中找不到一些未記錄的選項,要發現這些gem,請訪問 https://ss64.com/nt/ 或其他資源。

我建議在第一次使用特定命令時使用幫助,或者作為可用選項的提醒。嘗試將它用於本文中提到的任何其他命令,甚至幫助命令本身。在命令提示符下輸入這個:

help help

顯示help命令的文件。

重要:

跟隨任何批處理命令使用/?檢索相同的資訊。即輸入set /?工作方式與幫助集相同。以下兩個命令都表示檢視某個命令的幫助資訊:

help set
set /?

總結

批處理編碼可能很複雜,甚至像設定變數這樣看似簡單的事情也可能有一些細微差別。在本文中,我們詳細介紹了set命令及其怪異之處,並將其與setx命令進行了比較,後者可以持久地設定變數。您還學習瞭如何解析變數並在控制檯上顯示它們。現在,您可以在bat檔案中新增註釋,將命令分隔符用於多種用途,最重要的是,可以快速訪問任何命令的文件。

下一步,我們將進一步討論變數,特別是變數的作用域。我們將討論如何定義變數在何時何地擁有某些值,以及如何啟用延遲展開的強大功能。

本文由部落格一文多發平臺 OpenWrite 釋出!

相關文章