Windows批处理学习(二)——批处理(2)
前記
本篇緊接上一篇繼續探索批處理腳本,上一篇主要介紹了批處理所支持的數據類型以及批處理中常見的符號所表示的意義,這一篇則介紹批處理的常見命令語句的使用方式。閑話少說,直入正題。
DOS批處理的使用
任何程序設計語言除了提供數據類型的支持、特殊符號的操作處理支持,當然還需要提供分支、循環、跳轉語句的支持才能算的上是完善的語言。批處理的數據類型和特殊符號在上一篇已經介紹過,下面看看批處理中支持的分支語句、循環語句、跳轉語句和其他控制語句。
1.常見內置環境變量
批處理內置環境變量包括Windows的系統環境變量等,以下只是介紹接個在批處理中常用的批處理環境變量,至于批處理中引用Windows環境變量的用法與引用自身內置變量一樣,關于Windows環境變量可以自行查看資料。
1.1.cd——當前工作目錄
“cd”是MS-DOS目錄切換的命令,當然它也是MS-DOS提供的內部環境變量,用于引用當前批處理腳本的工作目錄完全路徑名;其實與無參數的“cd”命令的返回結果一樣,當作為環境變量引用的時候比較方便,可以直接使用“%cd%”表示當前工作目錄。
1.2.date——當前系統日期
“date”是MS-DOS提供的日期管理命令,同時也是MS-DOS提供的內部環境變量,用于表示當前系統日期,在Windows中通常與右下角日期格式一致。在批處理中可以直接使用“%date%”獲取當前系統日期。
1.3.time——當前系統時間
“time”是MS-DOS提供的時間管理命令,與“date”命令一樣也是MS-DOS的內部環境變量,用于表示當前系統時間,在Windows中通常與右下角時間格式一致。在批處理中可以直接使用“%time%”獲取當前系統時間。
1.4.random——0~32767之間的隨機數
“random”是MS-DOS提供的隨機數內部環境變量,該變量返回的是一個0~32767之間的隨機十進制數值。所以當我們需要使用隨機數的時候可以直接使用“%random%”來獲取。
1.5.errorlevel——錯誤級別變量
“errorlevel”可譯為“錯誤級別”,是MS-DOS(批處理)內置的用于監聽某些語句執行成功與否的變量。可以將它看作批處理中某一句代碼的返回值,它的結果是一個數值類型的代碼,每一個代碼都表示一種錯誤級別;它與每一條語句進行綁定,也就是說每一條語句都會返回一個錯誤級別代碼并賦值給“errorlevel”變量,當然也有例外的情況,除過“pause”,“cls”,“set”,“echo”,“rem”,“path”,“title”等命令語句外大部分的文件和目錄處理命令行都會返回錯誤級別代碼。至于哪些語句可以返回、哪些語句不返回可以自己測試看看。
當某一條語句執行成功時將返回“0”,即“errorlevel”等于“0”時表示語句執行成功;如果執行失敗則返回對應的代碼,也就是說如果“errorlevel”為非“0”的結果都可以視為上一句代碼執行失敗。也就是說如果返回了錯誤級別代碼就會直接賦值給“errorlevel”變量,之前的值就被覆蓋了,如果沒有覆蓋就說明該條語句沒有返回錯誤級別代碼。
從上面的介紹可以得知,單單憑借“errorlevel”變量來獲取某條語句執行結果是不準確的,因為部分語句是沒有錯誤級別代碼返回的,所以我們可以知道當“errorlevel”變量的值不為“0”時就代表某處語句發送了錯誤。“errorlevel”變量可以與“if”條件語句一起使用來進行判斷。
1.6.cmdextversion——命令行版本變量
“cmdextversion”可譯為“CMD擴展版本號”,是MS-DOS提供的命令行擴展版本號常量,它一般與MS-DOS發行版本有關,第一個版本的時候改變量的值為“1”,每次對命令擴展名有相當大的增強時,版本號會增加一個。需要注意的是只有當命令擴展名被啟用的時候才存在變量“cmdextversion”。
常常使用“cmdextversion”來檢測命令行環境,例如在第二個版本中新增了一個擴展,則在第一個版本中是無法使用的,需要在執行前檢查版本是否為“2”,如果是則可以成功執行,否則無法執行。實質該變量幾乎用不到。
1.7.cmdcmdline——命令行執行程序
“cmdcmdline”可譯為“CMD命令行”,是MS-DOS提供的命令處理器命令行引用的常量,它一般返回的是MS-DOS執行解釋器的完全路徑名。
1.8.path——執行路徑
“path”可以理解為“執行路徑”,當指定一個程序名稱后會首先在“path”指定的執行路徑目錄中進行程序搜索,如果搜索到則執行。“path”也可以是一個命令,同時也是一個內置變量,可以通過“%path%”來引用當前批處理程序的執行路徑信息,默認為Windows系統環境變量中的“path”變量值。
2.批處理控制語句
2.1.pause——批處理暫停
“pause”命令用于暫停當前批處理程序的執行,并不是終止,只是暫時的停止執行并可以及時恢復執行過程。我們進程會見到一個批處理執行完成后必須按一下鍵盤,才能退出批處理程序,這就是使用了“pause”的效果。當執行到“pause”默認的會在批處理控制臺顯示“請按任意鍵繼續...”字樣,當按下任意鍵時則恢復,繼續執行批處理程序。大多數的情況下都會使用到該命令,用法如下:
pause [...]
沒有任何參數的“pause”命令的實質就是輸出“請按任意鍵繼續...”并監聽按鍵事件觸發,當觸發按鍵后則終止暫停。
默認情況下,批處理文件一次執行完畢后就自動退出,就是我們看到的大多數情況下“一閃而過”的情況,如果我們想在批處理控制臺輸出什么信息則都無法查閱;現在就可以使用“pause”命令在批處理執行完成退出之前進行批處理程序的暫停操作,則就可以保留MS-DOS解釋器的窗口,從而查看MS-DOS的控制臺信息。我們來分析一下的代碼:
|
1 2 3 |
|
保存為“.bat”文件后執行可以看出,第一條語句執行的結果為“請按任意鍵繼續...”并等待按下任意鍵;第二條語句執行的結果為什么也沒有輸出,而是在當前工作目錄中新建了一個名為“a”的文件,內容是“請按任意鍵繼續...”,同時等待按下任意鍵;第三條語句執行的結果是沒有輸出內容和新建“nul”文件并等待按下任意鍵。來分析一下代碼,“>”用于將命令的執行響應信息輸出到指定的文件,所以“pause > a”會將“請按任意鍵繼續...”輸出到名為“a”的文件中,那么為什么“pause
> nul”沒有輸出到文件呢?
“nul”是一個特殊的字符串,在批處理中它表示“空字符”,它是一個概念上的空字符,表示沒有值,不是我們所說的空白符。上面的例子中的“pause > nul”意思就是說輸出空內容,所以即不輸出內容,也不輸出到文件。也就是說,我們可以使用“pause > nul”來取消“pause”命令的輸出內容。
2.2.echo——回顯設置
關于批處理的回顯問題,在上一節已經講到過,“回顯”就是打印要執行的命令語句,也就是每執行一條命令語句,都會先打印出來,然后在執行,當然這樣查看程序執行過程比較混亂,所以大多數情況下需要關閉回顯功能。上一節提到了“@”符號作為命令的前綴用于關閉該命令的回顯功能,如果要關閉所有的命令回顯功能,則需要在每一個命令前加上“@”符號,比較繁瑣,下面就來介紹一種簡單的處理方式——“echo”命令語句。
“echo”命令語句在批處理中,有兩個作用:其一就是控制當前批處理程序的回顯打開或關閉的狀態設置,其二就是在MS-DOS解釋器控制臺輸出信息。第二種作用前面已經用到很多次了,可以自行嘗試一下。下面來看看使用方式:
echo [ON | OFF]
echo 信息
echo符號 [ON | OFF | 信息]
首先來看第一種方式,演變為“echo”、“echo on”或“echo off”三種方式,其中無參數的“echo”命令用于查看當前“echo”狀態(即回顯狀態),默認情況下是開啟的;“echo on”命令可以開啟回顯;“echo off”命令用于關閉回顯,“echo off”的關閉可以適用與當前批處理程序,如果沒有顯示打開,即使用“echo on”命令,則當前批處理的回顯狀態一直處于關閉狀體,所以我們可以使用“echo
off”來代替繁瑣的“@”命令回顯屏蔽符號。例如我們最常用的兩種方式:
|
1 2 |
|
或
|
1 |
|
第一種方式我們調用了“echo off”命令關閉了當前批處理的回顯狀態,而“echo off”命令在執行前,回顯是開啟的,所以使用“cls”來清空屏幕內容;第二種發送直接使用“@”符號屏蔽“echo”命令的回顯功能;從而達到關閉所有回顯狀態。關于回顯狀體的設置,我們通常都在批處理的開頭設定,因為這樣比較合理,所以建議使用“@echo off”命令。
再來看第二種方式“echo 信息”,可想而知用于在控制臺輸出“信息”,其實這個信息就是你要輸出的字符串,這種方式比較容易理解。要輸出的內容緊接“echo”命令之后,注意必須使用空白符進行分割。我們來看下面的例子
|
1 2 3 |
|
保存為批處理文件并執行,可以看成在控制臺只輸出了“Hello World!”信息,沒有其他信息,可以看出“@echo off”關閉回顯功能已經起效。
最后看第三種方式“echo符號[信息]”,為什么會多出一個“符號”呢?首先看看我們如何輸出“off”和“on”字符,可見使用第二種方式執行后實質就是第一種方式設置回顯狀態的命令,根本達不到輸出“off”或“on”的目的。所以批處理提供了一種特殊的方式來輸出像“off”或“on”這樣的特殊命令字符,使用“echo+符號+字符”的方式來輸出。例如:
|
1 2 3 4 5 |
|
保存為批處理文件并執行,輸出的內容為:
off
(空行)
msg
上面的例子中,我們使用了特殊符號“.”,從例子可以看出無信息的“echo.”表示的是輸出一個空白行,有信息的“echo.信息”命令等同于“echo 信息”輸出信息用法。
事實上,批處理輸出空白行的方式有多種,都是使用“echo特殊符號”的方式輸出。當特殊符號后緊接特殊命令字符的時候,特殊符號用于將特殊命令字符轉義為普通字符;當特殊符號后緊接普通字符是直接輸出,類是于“echo 普通字符”方式。批處理中對“echo”命令提供的“特殊符號”有數十種,也就是說輸出空行的命令有多種方式。其中提供的特殊符號包括“=”、“,”、“;”、“+”、“/”、“[”、“]”、“:”、“.”、“”,使用“echo”集合任何一種特殊符號都可以輸出空白行。
可以將上面的特殊符號分為三組,第一組有“=”、“,”、“;”,它們默認都是批處理中的特殊分隔符號,其實可以將分隔符看作命令參數或選項的一部分,通常批處理命令在執行帶有分隔符的參數是會直接跳過第一個符號,也就是分隔符,而“echo”命令跳過分隔符后其后的字符為“NUL”,所以輸出了空行,而當分割符為“空白符”時會跳過并解析其后的字符是否是命令參數;第二組有“+”、“/”、“[”、“]”,它們不是特殊的分隔符,所以會將其作為一個整體進行解析,但是“echo/”等又不是MS-DOS命令,所以會作為外部命令來搜索和執行,它們可以作為外部命令進行執行;第三組有“:”、“.”、“”,既不是特殊分隔符,也不是外部命令,在執行的過程中,會嘗試自動修復命令進行命令的修復轉換,所以它們的效率是極低的。(信息來自“批處理技術內幕”介紹)
通過后面的簡單介紹其實為了說明一定,從執行效率上來將,當使用“echo”命令輸出空行時可以優選考慮使用“echo=”或“echo,”或“echo;”命令,上面所列車的三組符號中,每組的效率依次遞減。
2.3.rem/::——代碼注釋
任何一種編程語言,都必須存在注釋標識才能讓別人讀的懂。批處理腳本同樣也提供了代碼注釋功能,主要通過“rem”命令來實現文檔注釋說明。“rem”命令用于在批處理或“CONFIG.SYS”文件中標注注釋信息,用法與“echo”輸出命令一樣,在命令后標準一段字符串作為注釋信息。使用方式如下:
rem 注釋說明信息
“注釋說明信息”可以是任意文字,也可以是一條命令語句,被注釋的語句和文字不參與解釋執行。例如:
|
1 2 3 4 |
|
保存并執行的結果為輸出一個空行,而“rem”后的“echo”語句并沒有執行。
在批處理中還存在符號“::”與“rem”命令的作用一致,可用于語句的注釋說明。用法與“rem”也一樣,如下:
::注釋說明信息
“::”是一個特殊符號,并發批處理腳本規范的注釋命令,在批處理中使用“::”標注的語句或字符串,作為無效信息,在執行過程中將直接忽略;而“rem”標識則會解釋為“rem”命令的作用。也就是說在作用上它們是相同的,但是在原理上就不同了。其實“::”用于彌補“rem”命令的某些不足存在的,在某些特殊的情況下,使用“rem”命令注釋帶有“>”、“<”、“>>”、“|”等特殊符號的時候不能達到預想的效果,但是可以使用“::”來進行注釋。
2.4.set——變量管理
變量,一般的編程語言中都存在這個名稱,它表示一個可變的量,可以在程序中寄存一個數據項,并在其他的地方引用。從批處理支持的數據類型來看,批處理腳本中變量的類型應該有字符串和數值兩種。講到變量,就得提提變量的名稱了,批處理腳本中對變量的名稱沒有做任何規定,可以是任意符號或字符串,當然也可以是數值,所以說批處理腳本是比較弱智的。
批處理中的變量主要使用“set”命令來維護和管理,而在批處理中的變量也稱為環境變量。批處理規定的“set”命令用法比較多,主要有以下四種用法。
1.“set”命令查看變量
“set”命令可以用于查看變量信息,它返回的是所有符合的變量列表,格式為“變量名=值”。用法比較簡單,如下:
set [變量名前綴]
這里“變量名前綴”的意思是指“set”命令會在所有變量中進行查找,如果某個變量名的前綴(從第一個字符開始到第N個字符)與所給定的變量字符串相匹配則將改變了視為要查找的變量,是一種前綴查找方式。當沒有指定任何變量前綴時則列出所有的變量列表。
2.“set”命令管理字符串變量
“set”命令可以實現字符串變量的定義和刪除等操作。用法比較簡單,如下:
set 變量名=[值]
這里使用了一個“=”緊跟在變量名稱后,表示定義一個變量并進行賦值,這里如果把“=”省略了則變為查看變量命令了。因此當需要定義變量的時候不可缺少“=”,“值”是可選項,當存在時則表示給當前變量賦值;如果不存在則表示刪除當前變量,也就似乎給變量賦空值。可以參考下面的例子:
|
1 2 3 4 5 6 |
|
保存為批處理文件并執行,輸出的內容為:
var=abc
var=
當給指定變量賦空值時表示移除該變量。
3.“set”命令管理數值變量和運算
“set”命令不僅可以管理字符串變量,同樣可以管理數值類型的變量。批處理中使用“set /a”命令來實現數值的運算操作,“/a”是“set”的一個選項,表示其后的字符將被作為數值和算術操作符進行處理,如果不是數值將提示錯誤。用法如下:
set /a 數值表達式
這里的“數值表達式”不是一個固定的值,而是一種由數字和符號組成的任何一種算術表達式。表達式可以包含前面介紹的任意一種或多種“數值類型符號”,具體符號可以參考具體說明。例如,“set /a result=123+345”,則表示將“123+345”的計算結果賦值給“result”變量;而“set /a 123+345”在表示計算“123+345”的結果;同時還支持簡單的位運算等,支持“()”優選運算,支持“,”多個表達式同時運算等特點。例如:
|
1 2 3 4 5 6 7 |
|
保存為批處理文件并執行,輸出的內容為:
算術運算:1+2=3
字符串:1+2=1+2
從例子可以看出,如果要進行數值運算,必須使用“set”命令的“/a”選項來標明。
4.“set”命令實現控制臺輸入
下面來介紹“set”命令的另一個擴展功能,從控制臺或其他設備或文件將信息讀取一行字符串并賦值給指定的變量。使用“/p”選項來啟用這個功能,用到的較多的地方就是讀取從控制臺輸入的字符串。當解釋器執行到“set /p”命令時會等待用戶的輸入完成,一般使用回車鍵表示輸入完成;在輸入過程中可以使用“CTRL+C”快捷鍵強制退出輸入狀態。用法如下:
set /p 變量名=[值]
只是在定義字符串變量的操作之前加上了“/p”選項,其中“/p”選項表示將啟用控制臺輸入功能,并將輸入的內容賦值給“/p”后指定的變量名,注意“=”不能缺少。當然也可以賦給變量初始值,但是當輸入完成后變量將被重新賦值。例如:
|
1 2 3 4 |
|
保存為批處理文件后可以自行測試。
2.5.cls——清屏
“cls”命令,在MS-DOS那一節已經講過了,主要用于清除當前屏幕(包括當前語句)中的所有顯示信息,當感覺屏幕內容較多或較混亂時可以使用,用法比較簡單,它沒有多余的選項。下面看一個例子,使用“cls”命令清除回顯內容實現“@echo off”命令的效果:
|
1 2 3 4 |
|
2.6.color——批處理顯示顏色設置
“color”語句用于設置當前批處理MS-DOS控制臺的前景(顯示字體)和背景顏色,可以使用該命令來設置當前會話中別致的命令行窗口。用法如下:
color [前景顏色值[背景顏色值]]
“color”主要用于設置MS-DOS控制臺顏色值,MS-DOS系統使用的十六進制的數值來表示16種顏色,數值與顏色描述表如下:
| 顏色值 | 顏色描述 | 顏色值 | 顏色描述 | 顏色值 | 顏色描述 |
| 0 | 黑色 | 6 | 黃色 | C | 淡紅色 |
| 1 | 藍色 | 7 | 白色 | D | 淡紫色 |
| 2 | 綠色 | 8 | 灰色 | E | 淡黃色 |
| 3 | 湖藍色 | 9 | 淡藍色 | F | 亮白色 |
| 4 | 紅色 | A | 淡綠色 |
|
|
| 5 | 紫色 | B |
淡淺綠色 |
|
|
針對“color”語句來說,無參數的“color”語句可以將當前MS-DOS控制點前景和背景顏色還原為默認值,默認前景為白色字體,背景為黑色;對于有參數的“color”語句,第一個顏色值表示前景顏色,第二個顏色值表示背景顏色;如果只有一個值則表示設置前景顏色,也就是顯示文本顏色。
有一點需要注意的是,如果前景和背景顏色值相同時會導致顏色沖突,所以MS-DOS會將“errorlevel”錯誤級別設置為1,表示設置顏色異常;也即是說MS-DOS不允許前景和背景顏色設置為同一個顏色值。
2.7.title——批處理程序標題設置
“title”命令語句用于設置當前執行批處理命令提示窗口的窗口標題,和“color”命令差不多都用于設置批處理程序的。當需要自定義命令行窗口標題是可以使用該命令實現。用法比較簡單:
title 標題內容
只需要在命令后緊跟標題信息即可。理論上將“title”為設置批處理標題,實際上它用于改變批處理標題,批處理程序默認的標題為當前“cmd.exe”程序的執行路徑,當執行到“title XXX”命令時,會將批處理程序運行窗口的標題更改為“XXX”字樣信息,如果再執行一次“title aaa”則會修改為“aaa”標題。
2.8.more——分頁顯示
“more”命令語句用于分頁顯示命令語句響應的內容,也就是控制臺輸出的內容。當某個命令語句的輸出信息太多時就比較凌亂,可以使用“more”命令來實現分頁輸出的效果。之前在介紹“type”命令的時候使用過了“more”語句,當時使用的命令語句是“type a.txt |more”,這只是“more”命令的常見的用法,實質上“more”主要用于查看文件內容。
1.分頁查看控制臺顯示內容
當一個命令語句的響應信息較多時,可以使用“more”命令來實現分頁查看的效果,常使用管道重定向符號“|”將命令行的輸出信息作為“more”命令的輸入信息進行處理。用法如下:
命令行語句 | more [more命令選項
從用法規則上看,“| more”命令作為某個命令語句的子語句,其中管道重定向符號“|”用于將命令行語句的輸出信息作為“more”命令的輸入內容進行處理,從而達到對命令行輸出信息的分頁查看效果。
2.分頁查看文本文件內容
“more”命令不僅可以接收MS-DOS控制臺的輸出信息,同樣可以接收MS-DOS從文件讀取的信息,這種用法非常類似“type .. | more”命令查看文件內容的用法。用法如下:
more [more命令選項] [<] [files]
“more”命令可以替換“type”來實現文件內容的友好顯示。其中輸入重定向符號“<”是可選項,當然為了標準可以明確標識;當要查看的文件未指定時,則接下來的輸入信息將作為查看的內容,如果要同時查看多個文件,則文件名需要使用空白符分割,實質是將文件內容拼接后顯示的。
“more”命提供豐富的處理選項,可以通過“more/?”或者“help more”命令來查看,其中“/C”選項可以在顯示下一頁內容前清除屏幕信息;“/S”選項可以將多個空白行縮為一行進行顯示;“/E”選項可以啟用“more”名的擴展功能,從而實現對子命令的支持,例如可以通過“S n”子命令來跳過下一頁的n行信息等,具體說明可以查看使用說明。
2.9.if——條件判斷(分支)語句
“if”語句是批處理中的條件分支語句,表示的意思就是“如果...則...否則...”,大多用在批處理程序中的條件處理部分。“if”語句在批處理中使用的是比較廣泛的,例如要查看某個文件,則首先要確定該文件存在才可以查看,否則MS-DOS會拋出錯誤信息,這個時候就可以使用“if”語句進行判斷。“if”命令語句是通過條件成立與否來決定語句的執行,這里的條件成立和條件不成立可以理解為“true”和“false”,但是批處理中不存在這兩個常量。“if”語句所表達的意思是只有當條件成立時才會執行指定的命令語句,主要有以下幾種用法。
1.判斷信息是否相等(“==”)
“if”命令語句就是用于條件的判斷,然而由于批處理腳本本身比較弱化,所以初始的MS-DOS只能支持信息相等的比較,也就是只支持“==”操作符。用于比較字符串與字符串、變量與變量、變量與字符串之間是否相等,如果相等則表示條件成立。用法如下:
if [not] 信息比較表達式 (
命令行1
) else (
命令行2
)
這里的“信息比較表達式”的格式為“字符串1==字符串2”或“變量1==變量2”或“變量==字符串”的形式,也即是說只能使用“==”進行字符串或變量之間的比較,上面的“not”表示相反操作,不做多的解釋,來看下面的例子:
|
1 2 3 4 5 6 7 |
|
保存為批處理文件,執行既可以看到效果,可以自行修改,添加“not”試試。
2.判斷錯誤級別信息
錯誤級別“errorlevel”是MS-DOS的內置環境變量,在上面已經介紹過,主要用于保存上一條命令語句是否執行成功,成功則返回0,失敗或錯誤則返回相對應的錯誤級別碼。然而“errorlevel”是內置環境變量,所以可以使用下面的方式判斷:
|
1 2 3 4 5 6 7 |
|
然而“if”語句提供了一種特殊的錯誤級別判斷方式,如下:
if [not] errorlevel number (
命令行1
) else (
命令行2
)
這種方式并不是使用變量的方式進行引用,而是作為關鍵字使用,“number”表示一個錯誤級別碼,“not”表示相反操作,不做多的解釋。使用這種方式比較簡潔。
3.判斷文件是否存在
在上面已經提到關于文件是否存在的判斷,“if”語句提供了一種特殊的文件判斷方案,用法如下:
if [not] exist filepath (
命令行1
) else (
命令行2
)
其中“exist”是關鍵字表示“存在”,“filepath”表示要判斷的文件路徑,如果檢查到指定的文件存在則執行對應的命令塊,“not”表示相反操作,不做多的解釋。多說無益,直接看例子:
|
1 2 3 4 5 6 7 8 |
|
上面的例子表示如果檢查到C盤存在“a.txt”文件則刪除該文件,保存為批處理文件試試即可。
4.判斷MS-DOS擴展版本號(擴展用法)
MS-DOS擴展版本號“cmdextversion”是MS-DOS的內置環境變量,在上面已經介紹過,當在使用某個新擴展特征時可以首先判斷版本號是否對應,不過該用法需要在啟用命令擴展之后才能使用,而命令擴展默認是啟用的,進行擴展版本號判斷是“if”語句的擴展用法。用法如下:
if cmdextversion number (
命令行1
) else (
命令行2
)
意思是說當當前批處理擴展版本號與給定的“number”值對應時執行“語句1”否則執行“語句2”,大多數情況下不會使用這個命令語句。
5.判斷變量是否存在(擴展用法)
變量是否存在的檢查是“if”語句的擴展用法,用法比較廣,可以判斷變量是否被聲明,然后在斟酌使用,不過該用法需要在啟用命令擴展之后才能使用,而命令擴展默認是啟用的,用法比較類似文件是否存在的判斷用法,如下:
if defined 變量名 (
命令行1
) else (
命令行2
)
當變量被聲明定義后“defined 變量名”才會成立,否則不會成立,具體實例可以自行編寫。
6.信息比較運算(擴展用法)
上面介紹過“if”默認情況下只支持相等比較運算,然后后續考慮則對“if”語句進行了命令擴展,使其可以支持多種比較運算操作,不過該用法需要在啟用命令擴展之后才能使用,而命令擴展默認是啟用的。用法與“if”相等比較運算的用法一致,如下:
if [/i] 操作數1 比較運算符 操作數2 (
命令行1
) else (
命令行2
)
其中操作數可以是字符串也可以是數值,同時還可以是變量;“/I”選項用于開啟比較過程中字符串大小寫忽略功能;在命令擴展下支持的比較運算符有:“equ(等于)”、“neq(不等于)”、“lss(小于)”、“leq(小于等于)”、“gtr(大于)”、“geq(大于等于)”六種,其中“lss”、“leq”、“gtr”和“geq”四種比較操作符主要用于對數值進行比較,當參與比較的字符串是字符串時,將被轉換為對于的ASCII碼進行比較;而“equ”和“neq”既可以比較數值也可以比較字符串。來看下面的例子:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
上面的例子可以說明“/I”的用法,以及其他命令擴展下的操作符用法,保存為批處理文件即可執行查看效果。
綜上所述,特別提示以上的“if”語句中的“else”子句是可省略的,“else”只是起到多分支的作用,表示當條件不成立時執行的處理過程,不必要時可以去掉。關于“()”表示范圍,用于表示多條語句執行的語句塊(批處理中的每一條語句都是以換行符作為結束符號的),也就是說當條件成立是會執行“if”后“()”內的所有語句,當只有一條語句需要執行時可以省略“()”,特別需要注意的是省略“()”時,命令和“if”語句必須寫在一行,當有“else”子句時必須使用“()”。【小提示:注意“()”與關鍵字之間的空格】
2.10.setlocal/endlocal——啟動/結束延遲環境變量擴展功能
前面已經介紹過變量的引用原理,就是查找變量名對應的值來替換“%變量名%”字符串,從而達到變量引用的效果,這個過程也稱之為變量擴展過程,這種過程可用于處理基礎的普通的變量,然而我們來看看下面的例子:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
按照正常的執行流程可以推斷出結果為“重置var的值成功[var=after]”,然而真實執行的結果并不是我們想象的,保存為批處理文件并執行輸出的結果為“重置var的值失敗[var=before]”。我們來看看為什么為出現這種情況?首先聲明了變量var的值為before,緊接著為一個“if”語句,又在“if”語句中對變量var進行重新賦值,然后在進行判斷,然而該程序在解釋執行的過程中,將“if”語句以及其內的“set”命令和“if”語句作為一整條語句進行解釋的,當遇到“%var%”時會自動查找“var”的值替換當前語句,也就是整個外層“if”語句中的所有“%var%”字符串,因此內部的“if”判斷條件中的“%var%”被替換成了“before”,所以永遠都不會與“after”相等。這就是變量擴展的過程,那么外層“if”語句中的“set
var=after”是否執行了呢?答案是肯定的,通過在程序末尾追加“echo var=%var%”可以看出。
通過上面的例子,可以得出一個結論就是批處理中的默認變量替換過程值針對一整條語句的,也就是說如果一整條語句中某個地方有變量的引用,則將會影響到該條語句中的所有變量引用,同一條語句中的所有變量引用會在同一時刻被替換為該變量對應的值。通俗的說,就是默認情況下,一條語句中的變量的值是固定的。
針對這個現象,批處理提出了延遲環境變量(簡稱延遲變量)的概念,主要用于對變量進行擴展,彌補普通變量的應用過程中的不足,通過延遲環境變量可以實現在一整條語句中改變變量的值。也就是說可以通過延遲環境變量概念來實現子句內部的變量聲明、定義和賦值等操作。批處理中給出了“setlocal”和“endlocal”命令來實現延遲變量擴展功能的開啟和關閉操作,來看看兩個命令的用法:
setlocal enableExtensions | disableExtensions
setlocal enableDelayedExpansion | disableDelayedExpansion
endlocal
“setlocal”命令有兩種用法,第一種用法用于啟動(enableExtensions)或者停用(disableExtensions)命令處理器擴展名功能,這個用法主要用于管理MS-DOS解釋器的命令擴展功能,默認是開啟的,一般很少用到;第二種用法就是現在介紹的用于啟動(enableDelayedExpansion)或者停用(disableDelayedExpansion)延遲環境變量擴展功能,默認是停用的。“endlocal”命令用法比較簡單,就一個單一的命令行,該命令行主要用于停用延遲環境變量擴展功能,命令執行后將會還原當前批處理的擴展功能為默認值,所做的環境變量的改動不在局限于當前批處理文件;實質上“endlocal”比較特殊,是可以省略的,也不是一定要與“setlocal”成對出現,當一個或多個“setlocal”沒有強制使用“endlocal”時會在批處理文件的末尾自動執行“endlocal”命令來還原初始默認設置。
當開啟延遲環境變量的擴展功能后,對環境變量的修改和引用將會擴展到整個批處理程序中。下面來看看如何使用延遲環境變量的擴展功能?現在使用延遲環境變量擴展功能解決上面遇到的問題,代碼如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
在這段代碼中,首先使用“setlocal enableDelayedExpansion”語句啟用了延遲環境變量擴展功能,保存為批處理文件并執行的結果則為預想的效果“重置var的值成功[var=after]”,代碼中并沒有強制使用“endlocal”語句停用延遲環境變量擴展功能,但是MS-DOS解釋器會在程序的末尾,也就是“pause>nul”語句之后自動調用“endlocal”命令重置MS-DOS環境默認值。
但是上面的代碼與之前的代碼還有一處細小的區別,就是這里使用了“!xxx!”的方式來引用變量。然而為什么要使用這種方式呢?“%xxx%”的方式是否可行?答案可想而知“%xxx%”的方式肯定不可行。之前已經介紹過“%xxx%”方式的變量替換原則,當在一條命令的整體語句中時,如果首次遇到“%xxx%”的字符串,則會自動查找并替換該整條語句中的所有“%xxx%”字符串為指定變量的值;正是這個原因,所以提出了延遲環境變量擴展的概念,延遲環境變量擴展就是為了解決整條語句中所有變量被替換的問題,然而在提出延遲環境變量擴展概念的同時擴展了“!xxx!”的變量引用方式,主要用于區別默認的“%xxx%”變量引用方式,而且“!xxx!”變量引用方式只能在延遲環境變量擴展功能開啟的環境中才能被解析。
來總結以下,關于延遲環境變量擴展的用法,延遲環境變量擴展功能主要用于解決像“if”、“for”以及各種復合語句(使用邏輯運算符拼接的語句)等中,用于在語句內部引用修改后的變量,因為默認情況下語句中的變量是被提前替換的,使用延遲環境變量則可以延遲替換過程到解析到該變量時;使用“setlocal enableDelayedExpansion”語句開啟延遲環境變量擴展功能后,只能使用“!xxx!”的方式引用變量,表示該變量將被作為延遲環境變量進行處理,如果使用“%xxx%”方式引用將繼續作為普通變量處理;開啟延遲環境變量擴展功能后可以在必要的時候強制使用“endlocal”或“setlocal
disableExtensions”語句停用該功能,默認在程序結尾自動調用“endlocal”語句進行重置。
2.11.for——循環語句
對于一門程序語言,單單提供分支語句是不夠的,必須還要提供循環語句才能滿足重復執行某一項任務的需要。在批處理腳本程序中同樣提供了循環語句——“for”語句,主要用于實現重復執行某一項命令,“for”語句設計由衷用于對一組文件中的每一個文件執行某項特定的命令操作,同時也可以擴展為對一個集合中的每一個元素執行某項特定的命令操作。“for”語句主要有一種基本用法和四種擴展用法,下面將一一介紹。
1.循環遍歷元素(基本用法)
批處理中的循環主要用于遍歷集合中的元素,語法結構如下:
for %%臨時變量名 in (集合列表) do (
命令行
)
基本結構比較簡單,使用“for...in...do”的方式,字面意思就是“把在集合中的所有元素都執行一遍操作”,使用這種方式將一個集合中的所有元素都執行一次相同的命令。
在循環遍歷過程中如何取得每一個元素呢?在批處理中的循環語句中提供了一個臨時變量用于保存每一個元素(不區分元素類型),從語法上可以看出“%%臨時變量名”就是這個臨時變量。這里的臨時變量的聲明與之前將的環境變量的聲明不大一致,環境變量的聲明直接使用“xxx”方式,而在“for”語句中的臨時變量聲明使用“%%xxx”方式。至于為什么這樣規定,我也沒有搞清楚,之前介紹過“%”有轉義的作用,所以這里的第一個“%”可以看作為轉義字符,正式的變量名為“%xxx”,或許是為了區分環境變量(語句外定義)或語句內變量。需要注意的是臨時變量“%%xxx”中的“xxx”可以是任意字符,而且必須是單個字符,當為英文字母時其名稱是區分大小寫的,為什么只能為一個字符下面會通過例子介紹到。由于“%%xxx”格式的臨時變量保存的是一個元素,所以可以直接在“for”語句內部使用“%%xxx”方式來訪問該臨時變量,這一點也與環境變量的訪問方式不同。
關于集合列表中的值,可以是任意值,多個值使用英文狀態的逗號(“,”)分割開來,而且集合無論有多少值都必須使用“()”括起來,表示一個集合范圍。上面說過“for”語句的由衷就是為了遍歷一組文件,所以不管集合列表中是什么值,都作為文件名來處理,無論該文件是否存在都會進行遍歷,默認情況下只是作為文件名(字符串)進行處理,當然還可以進行更高級的擴展處理。也就是說,事實上看到的字符串,實質是作為文件名進行處理的,所以元素支持通配符“*”和“?”,“*”表示當前工作目錄下的所有文件。多說無益,看下面的例子:
|
1 2 3 4 |
|
上面的例子用于變量所有的元素,其中1,3,5,7將作為文件名進行輸出。保存為批處理文件并執行可以看看結果。
|
1 2 3 4 5 6 |
|
上面的例子用于變量每一個元素,其中“*”表示當前工作目錄下的所有文件,并將文件名打印輸出,保存為批處理文件執行即可看到效果。
上面的兩個例子足以說明“for”語句的基本用法,其中如果要重復執行的語句為多條語句時必須使用“()”將多條語句括起來,與“if”基本相識;如果是單條語句可以直接寫在“do”后面。
2.循環遍歷目錄(擴展用法)
批處理中的“for”語句默認是用于遍歷文件列表的,如果想變量一個目錄列表又該如何操作?在批處理的“for”語句結構中提供了一個“/D”選項,可以將集合列表中的元素值強制作為目錄名稱進行處理。語法結構如下:
for /D %%臨時變量名 in (集合列表) do (
命令行
)
該用法只是在基本用法的基礎上,多了一個“/D”選項用于修飾臨時變量,主要是將臨時變量的值進行目錄檢查,如果是目錄則取用,否則則丟棄。看下面的例子,在C盤下的文件夾中存在文件和子文件夾:
|
1 2 3 4 5 6 7 |
|
通過上面的代碼執行結果的對比可以看出“/d”選項的作用,用于匹配目錄名稱,忽略文件。
3.循環遍歷指定工作目錄下的文件或目錄(擴展用法)
在第二個用法的例子中開頭有一句“cd C: est”將當前工作目錄切換到C盤的test目錄,如果不指定則默認工作目錄就是當前批處理所在的目錄,這樣寫雖然很直觀當時相對比較麻煩。在批處理的“for”語句中提供一種指定工作目錄的方式,使用“/R”進行工作目錄的指定,用法如下:
for [/D] /R 工作目錄 %%臨時變量名 in (集合列表) do (
命令行
)
該用法是基礎用法的擴展用法,可以直接在“for”語句內指定要查找的工作目錄,使用“/R 工作目錄”的方式指定。指定后將在當前“工作目錄”中進行文件的查找遍歷。當然可以與“/D”一起使用,用于查找變量目錄,當與“/D”一起使用時“/D”修飾必須寫在“/R 工作目錄”的前面。下面我們來改寫第二個用法中的例子,如下:
|
1 2 3 4 5 6 |
|
保存為批處理文件并執行則可以看到執行結果與第二個用法的基本一致,只不過這個用法輸出的是文件或目錄的完全路徑名稱,這是“/R”選項的另一個特點。如果你細心,還會發現“/R”選項還可以查找變量到目錄下的子目錄或子文件,如果我們在C: est目錄下的某一個目錄下再添加一個文件或目錄,則同樣會打印輸出。
來總結一下“/R 工作目錄”的用法,可以查找當前工作目錄下的所有文件或目錄,包括子目錄下的文件或目錄,直到沒有下一層為止;每一個臨時變量保存的是文件或目錄的完全路徑名稱。也就是說使用這種方式我們可以實現目錄結構樹圖,可以自行嘗試一下。再來看看上面講到的兩種用法,基礎用法和“/D”選項用法只能查找當前工作目錄下的文件或目錄,而并不能進一步深入查找下一層文件或目錄。
4.固定頻率循環(擴展用法)
上面介紹的“for”語句主要用于文件管理中的循環遍歷操作,這些循環操作執行的次數都是受到工作目錄中文件或目錄的數量的影響,是不固定的;當我們需要執行規定次數的某一個操作時,又該如何實現呢?當我們要迭加一個數值又該如何實現呢?其實在批處理的“for”語句中提供了“/L”選項,專門用于實現數值范圍的遍歷操作,用法如下:
for /L %%臨時變量名 in (start,step,end) do (
命令行
)
從語法結構上看,添加了一個“/L”選項修飾操作,同時“集合列表”也固定了結構,是一個有start、step、end三個數值組成的列表,從語義上可以知道集合列表中的“start”表示循環的開始數值,“end”表示循環的結束數值,而“step”表示循環的遞增頻率數值;過程是第一次循環臨時變量將被賦值為“start”指定的數值,之后每一次臨時變量在原有值的基礎上增加“step”指定的數值,然后與“end”指定的值進行比較是否小于等于,如果是則執行下一次循環,否則跳出循環。舉個例子,如果我們要循環3次則列表集合可以寫作“(1,1,3)”,就是說臨時變量從1開始,到3結束,每一次循環后增加1;如果要打印輸出10以內的奇數,則可以寫作“(1,2,10)”。多說無益,來看下面的例子:
|
1 2 3 4 5 6 |
|
保存為批處理并執行既可以看到結果。“for”語句使用“/L”選項后,要求集合列表必須包含3個數值,其中第一個表示循環起始值,第二個表示循環頻率值,第三個表示循環結束值,這些值必須是數值,而且可以為正負數值。
5.高級擴展應用
上面已經介紹了“for”循環的幾種不同應用方式,但是不足以靈活多變,所以批處理還提供了高級擴展應用,包括文件內容循環遍歷、內容查找處理操作、動態執行命令行等功能。高級擴展應用使用“/F”選項進行開啟,用法如下:
for /F [操作選項] %%臨時變量名 in (集合列表) do (
命令行
)
擴展用法與上面介紹的幾種基本一致,不過這里在“/F”選項后包括一個“操作選項集合”,下面會介紹到。
首先來看看“集合列表”,集合列表可以是文件集合、字符串集合(我們知道文件都是擴展名的,或許可以簡單的區分為文件名或字符串)或命令集合。當集合中的元素為一個或多個文件時,則在進入循環語句時,當前文件和之前已經遍歷的文件都將處于打開狀態,并接受讀取等操作,處理包括讀取文件行(將文件內容以換行符分割或空白符截斷)并將每一行信息解析為一個或多個字符串(按操作語句指定進行解析分割),當為文件名時需要注意的是當文件名中有空格符號是需要使用“""”將文件名引用起來;當集合為一個或多個字符串時,必須使用“""”將字符串引用起來,則執行過程將會對每一個字符串進行一一處理;當集合類型為一個命令行語句時,命令行語句需要使用“''”括起來,則會對該命令行的響應輸出信息進行處理。例如:
|
1 2 3 4 5 6 |
|
這個例子就是變量“echo HelloWorld!”命令語句的輸出信息。
下面再來看看“操作選項”,這里的操作選項必須使用“""”括起來,可以包含一個處理選項或多個處理選項,多個處理選項之間使用空格符號進行分開,處理選項在該用法中是可選的。如果處理選項不存在,則臨時變量表示的是每一個文件或字符串或命令輸出的一行內容,這一行內容以空白符進行截斷;如果處理選項存在,則臨時變量表示的是每一個文件或字符串或命令輸出的一行內容中符號條件的部分內容。處理選項包括一下幾種(是一種子命令的方式):
| 選項表達式 | 說明 | 舉例 |
| eol=c | 指定忽略以“c”指定的字符開頭的元素,只能是單個字符(如果集合為文件則指忽略以“c”開頭的行) | eol=a(忽略a開頭的行) |
| skip=n | 指定忽略的元素數n,以第一個元素開始,只能為正整數(如果集合為文件則指跳過0-n行) | skip=3(忽略前3行) |
| delims=xxx | 指定以“xxx”作為元素的界定符號,默認以空格符或換行符作為元素界定符號。可以包括多個字符,某一元素從第一個字符開始算起包含其中的某一個字符則視為終止,其后的字符將被忽略(如果集合為文件則指以“xxx”作為行的界定符號) | delims=。(使用“。”作為換行符) |
| tokens=x,y,m-n | 表示取到每一個元素的第x字符賦值給臨時變量,取第y個字符賦值給當前臨時變量字母的下一個字母變量,取第m到n個字符組成的字符串賦值給下一個字母變量,一共可以有26個取值。可以使用通配符,*表示所有,?表示單個任意字符 | tokens=2表示取每一行的第二個字符;2,3表示取每一行的第二個和第三個字符;2-8表示取每一行第二個到第八個字符組成的字符串 |
| usebackq | 用于標記引號("")或('')中的為文件名或命令行 | usebackq |
上面列表所列的是“/F”選項下的所有操作選項說明,這些選項只有在“/F”選項下才可以使用。廢話不多說了,看下面的例子:
|
1 2 3 |
|
這段代碼是將“a.txt”元素作為字符串進行處理,截取“.”之前的字符并打印,保存為批處理文件并執行即可看到效果。如果我也要將“a.txt”作為文件名則可以在操作選項中加入“usebackq”選項。
“for”語句的“/F”選項擴展主要用于內容的循環查找操作,在查找過程中對應的臨時變量的操作存在一個特殊的擴展處理方式——自動變量擴展,比如說當使用tokens操作選項來取得每一個元素或每一行的某個或幾個字符時,可以自動以當前定義臨時變量名(單獨字母字符)為起點進行后續擴充,定義的臨時變量保存取得的第一類字符信息,下一個字符擴展的臨時變量則表示第二類字符信息,依次類推,規定最多只能擴充26個臨時變量(包括當前變量在內),是由于tokens選項最多只能指定26個值集合。來看下面的例子:
|
1 2 3 4 5 6 |
|
這個例子是將“DIR”命令的輸出信息作為遍歷內容,首先跳過前兩行,然后從第三個字符塊開始取值,使用默認的方式進行換行或截斷操作,其中第二個字符塊將作為“%%a”的值,第三個字節塊作為“%%b”的值,第三個之后的字節塊作為“%%c”的值。(目前我還沒找到什么特殊的規律,這個值只能靠查看結果才能知道所表示的內容是什么,臨時變量擴展雖然很方便但是使用需要謹慎,如果沒有取到值則會輸出“%變量名”信息,我并沒有很深入的去了解它,如果你有興趣,可以深入了解并整理一下結論和規律分享給大家)
2.12.goto/:——跳轉語句
“goto”從字面上理解就是跳轉的意思,“goto”語句就是批處理中提供的流程跳轉語句,何為流程跳轉?首先批處理的執行過程是自上而下順序執行的,默認情況下,批處理文件中的所有語句都會執行,不論上一條語句是否執行成功。如果在執行過程中遇到某種情況需要進行特殊處理,那么就需要改變執行的流程,不過可以使用“if”語句來實現流程的控制,從理論上也可以實現跳過部分語句代碼的過程,但是比較麻煩,需要使用“if”語句塊來實現,所以批處理提供了“goto”語句來實現標簽式流程跳轉。標簽式跳轉也就是說首先要定義一個標記,然后使用“goto
標簽”的方式跳轉到指定的標簽語句塊內,所以“goto”語句必須結合標簽實現執行流程的跳轉,在批處理中使用“:”來聲明標簽,來看標簽和“goto”語句的基本用法:
goto [:]標簽名
: 標簽名
命令行
批處理中規定,“goto”語句用于標簽式跳轉,其后緊接要跳轉到的標簽名稱(中間使用空白符分割);標簽的聲明必須使用“:”作為前綴,也就是說在批處理中以“:”開頭的字符串或語句都是標簽,其標簽后的命令行語句是該標簽的標簽體,只要沒有遇到“goto”跳轉語句則其后的語句都會執行;其實標簽體是一個模糊的概念,很多情況下它是混淆的。看下面的例子:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
上面的例子,從語法上看,定義有“a”標簽、“b”標簽和“end”標簽,從執行流程上看,“a”標簽和“b”標簽是混淆的,因為缺少標簽結束語句,所以在使用標簽跳轉的時候一定要為標簽體定義一個“goto”語句,表示跳出標簽體,如果是最后一個標簽則可以忽略。
使用“goto”必須注意,標簽體在必要的時候必須使用“goto”跳轉語句進行終結,否則其后的所有標簽或非標簽都會作為當前標簽的標簽體進行執行,正如上例一樣;其次還需要注意標簽結束時的“goto”跳轉語句,如果沒有需要,最好不要跳轉到當前標簽,否則會構成“死循環”,不斷的執行當前代碼體,理論上是無法退出的。看先一個的例子:
|
1 2 3 4 5 |
|
從執行流程上分析,這段代碼首先進入“start”標簽,然后跳轉到“start”標簽,然后在進入“start”標簽……從而構成了一個“封閉的回路”,會無窮的執行下去(這只是理論上的猜想,實際上當達到某一個次數后會自動停止)。因此沒有必要這種寫法是不可取的。最后,再來看一個例子,使用“if”和“goto”實現的簡單計算器:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|
上面的例子中使用了一個“goto :eof”語句,從運行的流程上看,如果沒有選擇則會跳轉到“eof”標簽,從結果上看,實質是退出了批處理文件,為什么呢?因為“eof”標簽是批處理中的默認標簽,用于跳轉到批處理文件的末尾,也就是最后一條語句的后,所以會直接退出批處理文件。這個地方不能直接使用“goto eof”,因為這樣會默認將“eof”作為自定義標簽進行處理,只能使用“goto :eof”方式。
2.13.start——批處理啟動
“start”的字面意思是“啟動”,無可異議在批處理中是用于啟動程序的。“start”命令比較獨特,可以啟動人任意的程序或文件,只需要指定程序或文件的名稱即可,可以是全名稱(如果不指定擴展名會按照環境變量自行查找匹配),執行跨磁盤的程序啟動。其實“start”命令是一個啟動程序的入口,用法如下:
start ["title"] [/I] [/MIN] [/MAX]
[/B] [command/program] [parameters]
其實“start”命令提供的選項操作比較多,可以通過“start/?”或“help start”命令查看,上面列出的是幾個常見的選項操作。其中“command/program”表示命令或程序名稱,“parameters”表示參數。
“start”命令主要用于啟動批處理程序,可以啟動當前批處理程序外的其他批處理文件,例如使用“start C: est.bat”可以啟動C盤下的test.bat批處理程序并在新的MS-DOS解釋器中執行,通俗一點的說就是在一個新窗口中打開并執行test.bat批處理程序。實質上“start”命令是以批處理文件默認關聯程序打開指定的文件,當然可以使用“title”選項來指定新窗口的標題,使用“/i”選項強制去掉引用舊窗口的環境變量,使用“/min”或“/max”選項指定新窗口是否最小化或最大化,使用“/b”選項強制進行窗口合并等,更多選項說明可以自行查閱。
同時“start”命令還可以啟動其它程序,包括可執行程序以及文件等,但是可能不會提供更多的選項操作。同樣的道理,“start”命令是以要打開的程序所關聯的默認執行程序打開當前程序或文件的。了解Windows系統應該知道文件關聯選項中的一些設置,其實文件都是通過命令語句打開的。
2.14.call——批處理調用
“call”的字面意思是“調用”,在批處理中“call”命令用于實現批處理文件的調用操作,事實上它不僅能實現批處理文件的調用,還可以實現標簽式調用,標簽式調用與“goto”的用法非常相識。“call”命令的用法如下:
call 批處理文件路徑 | :標簽名 [參數]
“call”命令可以在當前批處理文件中調動另一個批處理文件,也可以在當前批處理文件中調用某個聲明式標簽,從作用可以知道“call”共兼了“start”和“goto”的作用,其實還是存在一定的區別的。
首先來介紹一下“call”命令調用批處理程序文件,使用“call”語句調用批處理程序與“start”命令啟動批處理程序非常類似,只需要指定批處理文件完全邏輯名稱或相對路徑名稱即可,例如“call test.bat”語句既可以執行test.bat批處理文件。細心的你可以會發現執行的批處理文件并不會開啟新的解釋執行窗口,然后會將被調用的批處理的所有輸出顯示語句都打印在當前窗口,換句話說就是被調用的批處理程序繼承了當前批處理程序的執行環境,然后先退出被調用的批處理程序,最后在退出當前批處理程序,這就是“call”語句與“start”命令的最大區別,“call”的這個功能很類是“start
/b”命令,還一個區別是“call”命令沒有提供跟多的操作選項,但是可以在“call”語句后面拼接執行新程序時需要的參數(多個參數使用空白分割)。可以看下面的例子:
|
1 2 3 |
|
其中“test.bat”的內容如下:
|
1 2 3 |
|
從這個簡單的例子可以看成“call”命令的執行過程。其次“call”命令也具有調用其他可執行程序功能,與“start”命令使用一樣。
下面看一下“call”命令標簽跳轉用法,使用“call”語句實現標簽跳轉語句與“goto”語句的用法非常類似,只需要在“call”命令后緊接要跳轉的標簽名稱即可,唯一不同的是這里的標簽名稱需要指定“:”前綴,同樣可以在標簽名稱后拼接多個執行參數,看下面的例子:
|
1 2 3 4 5 6 7 8 |
|
這個例子可以說明“call”語句不僅能實現“goto”語句的功能,同時還可以傳遞參數。實際上“call”命令調用預先定義的標簽時,會將標簽語句視為一個批處理程序集進行執行,執行完該標簽的所有語句后會再次返回到“call”語句后繼續執行,這也是“call”標簽跳轉與“goto”標簽跳轉的另一個區別,“goto”標簽跳轉后會繼續向標簽后執行,不會自動返回到“goto”語句后。通常情況下,使用“call”命令來調用標簽語句時,標簽體的末尾應該使用一個“goto
:eof”語句來結束標簽體,當然也可以使用其他的語句,這樣做是為了可以編寫多個“call”調用的標簽體語句,避免混淆。
其次來看看關于“call”語句傳遞參數后如何訪問,在之前介紹“%”的時候介紹過“%num”(0=<num<=9)方式可以用來引用某些特殊命令語句傳入的參數,其中“num”表示參數的索引,從“0”開始,所以上面我們使用“%0”、“%1”、“%2”的方式來引用“call”傳遞的參數信息。(后面會繼續介紹)
2.15.cmd——啟動MS-DOS新窗口
“cmd”命令,我想學過電腦的人應該都知道,“cmd”實質是“command(命令)”的縮寫,用于啟動一個MS-DOS命令行解釋器窗口,準確的說是啟動一個MS-DOS(cmd.exe應用程序)的一個新實例。我們大多數是在運行窗口“cmd”命令來啟動一個命令行窗口,其實“cmd”命令還提供了很多操作選項用來設置當前MS-DOS解釋器的環境變量。例如可以使用“/T:fg”設置當前命令行的前景(“f”)/背景(“g”)顏色(顏色值請參考“color”命令);使用“/E:ON”(“/X”)或者“/E:OFF”(“/Y”)啟用或停用命令擴展功能,默認情況下是啟動的;可以使用“/V:ON”或“/V:OFF”啟動或停用延遲環境變量擴展功能,用“setlocal”具有一樣的作用。而且“cmd”命令還可以將一句字符串作為命令行語句進行解釋執行,用法如下:
cmd /S | /C | /K 字符串
其中字符串必須使用“""”引用,“/S”選項用于保留字符串的“""”并進行執行;“/C”或“/K”選項用于將“""”內部的字符串作為命令語句進行解釋執行。需要注意的是“/S”選項不能與“/C”或“/K”選項一起使用,而且如果字符串語句是多條命令語句需要使用“&&”符號進行分割。
2.16.path——執行環境路徑管理
“path”是Windows中比較重要的一個東西,在MS-DOS系統中同樣提供了“path”命令來定義當前批處理程序的資源路徑信息。當需要在批處理程序中調用某一個文件是必須先進入該文件所在的目錄,然后才能使用該資源;如果要引用另一個資源必須首選進入其所在的目錄(當然你也可以使用完全絕對路徑引用),顯然這種模式比較笨拙,我們可以首選使用“path”命令指定當前批處理工作所需的所有目錄,然后就可以在程序中直接引用資源名稱了,既可以減少相應的代碼量,也可以是程序更美觀。“path”命令的用法如下:
path 目錄完全路徑[;...][;%PATH%]
path [;]
使用“path”命令可以可以查看當前批處理程序或MS-DOS解釋器的執行目錄路徑;使用“path ;”命令可以將當前執行路徑置為空;使用“path dirs”可以設置當前執行路徑,其中“dirs”可以為一個目錄,也可以為多個目錄,多個目錄需要使用“;”分割,同時還可以在原有的執行路徑上進行路徑擴展,可以使用內置環境變量“%path%”來引用原有目錄。
“path”命令設置后,當程序中某個地方引用到某個資源名稱,則會在“path”指定的工作目錄中進行資源的查找,如果查找到了則引用,否則會導致錯誤。
2.17.exit——退出MS-DOS
“exit”命令在之前已經介紹過,這里在作一個簡單的補充說明。“exit”命令在MS-DOS解釋器用于退出當前“cmd.exe”程序,在批處理文件中用于退出并結束當前批處理程序,同時還可以擴展為結束某個進程。用法格式為:
exit [/B] [exitCode]
無參數的“exit”命令用于退出并結束當前命令行程序;“/B”選項用于強制指定當前退出的是批處理腳本程序而不是“cmd.exe”程序,如果在批處理教程外使用則用于退出“cmd.exe”程序;“exitCode”是一個代碼信息,不能與“/B”選項一起使用,代碼表示要退出的進程的ID值。
后記
本篇主要介紹了批處理程序中的內置環境變量,流程控制語句等批處理中常見的命令,包括“IF”、“FOR”、“GOTO”等語句,當然還有其他的不怎么常用的語句和命令等待著大家自行去發掘。介紹的內容可能并不一定全面,希望能諒解。
梳理知識,分享大家,互利你我!怕拍板磚,就不知道自己整理的對知識掌握的問題所在,找到問題才有所進步,歡迎大家踴躍的拍磚...
本文出自 “阿酷呆” 博客,請務必保留此出處http://akudy.blog.51cto.com/2277883/1257596
總結
以上是生活随笔為你收集整理的Windows批处理学习(二)——批处理(2)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 无刷新上传Excel后利用JQuery
- 下一篇: js-YDUI 移动端解决方案