關於批處理以及批處理常用命令的總結
阿新 • • 發佈:2019-02-19
本節學習有關批處理的一些比較瑣碎、但又比較有價值的一些知識,運用這些知識後,才有條件更好的實現的批處理的功能,並能使批處理擺脫黑白世界而顯得更加多姿多彩。廢話少說,開講啦~
【(一)環境變數 】
所謂“環境變數”,實際上就是C語言裡面的“變數”的意思。批處理的變數可以分為兩類,由系統定義的系統變數和由使用者根據需要自定義的使用者變數。
【 1、系統變數 】
批處理的一些變數是由作業系統事先定義好的,可以適用於任何批處理,我們稱這些特殊的變數為“系統變數”。系統變數有很多個,包括硬體類、作業系統類、檔案路徑類、系統時間類等。要檢視所有的系統變數,請新開啟一個cmd視窗,輸入set回車即可。對幾個比較常用的變數解釋如下:
ComputerName 計算機名,即右鍵 我的電腦--屬性--計算機名 選項卡中的“完整的計算機名稱”
ComSpec cmd.exe完整路徑名
HomeDrive 系統分割槽碟符,一般都是C盤,故而HomeDrive=C:
Path 可執行檔案預設搜尋路徑。這個東東非常重要!待會兒單獨講解…
ProgramFiles 就是系統的Program Files的路徑啦,一般都是C:/Program Files,這就是安裝軟體時預設的安裝路徑了
Prompt 個性化設定cmd提示符的必備武器!不過,我沒怎麼用過~
SystemDrive 包含系統根目錄的分割槽,其實就是HomeDrive了
SystemRoot 系統根目錄路徑,一般都是C:/WINDOWS
Temp、Tmp 檔案、程式等可使用的臨時目錄,預設是C:/WINDOWS/Temp或Tmp。幾乎所有的程式在執行時都會在這個目錄裡面“臨時”寫入檔案。一般情況下,程式寫入的臨時檔案都應該被該程式刪除,可惜的是,大部分的程式都很健忘,導致這個資料夾佔據的空間越來越大,自然也就使我們的系統增肥嘍。所以,我們要把它修改到其他分割槽,並且時時的清理裡面的臨時檔案。
UserName 當前使用者名稱,即所登陸的賬戶名
UserProfile 當前使用者的配置目錄,一般都是C:/Documents and Settings/%UserName%。預設情況下,我們的桌面就是這個目錄下面的“桌面”資料夾;我的文件就是這個目錄下面的“My Documents”資料夾。所以啦,往桌面上或我的文件裡面放東西就是放到這個資料夾下面了,也就是放到C盤了,重灌系統時要覆蓋C盤內容的,所以桌面上或我的文件裡面的東西當然就會Gone with the Wind了~解決方法有兩個,一是保持良好的習慣,不把重要檔案放到這兩個地方;二是,修改預設設定,將這兩個資料夾都移到其他分割槽。
WinDir 作業系統路徑,其實就是SystemRoot了
【 2、使用者變數 】
編寫批處理程式時,使用者根據需要自己定義的變數稱之為使用者變數。使用者變數類似於C語言裡面的變數,僅僅在定義該變數的程式中有效。
使用者變數由set命令定義,這是批處理中非常非常重要的一個操作,從而使set命令成為批處理裡面使用頻率最高的幾個命令之一。關於set命令的使用,參考set /?,本教程也會在後面對其進行講解。
【 3、變數引用 】
前面的幾節課裡面,我們已經看到了如何引用變數,即直接用變數名操作變數,通過"%"或"!"來獲取變數的值。其中,只有在for語句裡面重複對同一變數多次賦值時才需要使用"!",並且在使用"!"呼叫變數時,要首先“啟用延遲環境變數擴充”,啟動命令為:SetLocal EnableDelayedExpansion。另外需要說明的是,“啟用延遲環境變數擴充”後,所有的"!"都將被視為“取變數值”的特殊符號,即使用"^!"也不能輸出符號"!"。若要輸出"!",則需要“停用延遲環境變數擴充”,命令為:SetLocal DisableDelayedExpansion
【(二)引數 】
跟C語言類似,在呼叫函式或其他批處理時可能需要傳遞引數。批處理的引數傳遞分為直接和間接兩種傳遞引數的方法。
【 1、直接傳遞 】
直接傳遞引數,即在使用call命令時,不使用任何引數,在子函式或子批處理裡面直接對主函式(也稱父批處理)裡面的變數進行修改。這跟組合語言裡面的引數傳遞方式類似。
直接傳遞引數舉例:
===============================================
@echo off
setlocal enabledelayedexpansion
set var=aCdehiM,?mnrstW y
echo %var%
call :deal
setlocal disabledelayedexpansion
set var=%var:?=!%
echo %var%
pause>nul
exit
:deal
set tm=!var!
set var=
for %%i in (6,3,11,11,16,15,1,4,11,5,12,13,9,0,12,7,15,14,5,10,2,16,18,8) do (
set var=!var!!tm:~%%i,1!
)
goto :eof
===============================================
可以發現,當我們把變數var作為引數賦予子函式:deal後,子函式對var的值進行了修改;當子函式返回後,主函式裡面的var的值就已經是子函式裡面var被修改後的值了。
該例子中,使用了本節課前面講到的setlocal enabledelayedexpansion和setlocal disabledelayedexpansion,前者保證了var在for迴圈裡面能夠根據我們的意願進行處理,後者保證了能夠正確輸出符號"!"。另外例子中還使用了命令set,利用set對字串進行了處理。還有一個地方使用了語句goto :eof,該語句相當於C語言裡面的return或組合語言裡面的RET,即子程式返回命令。需要說明的是,當子函式本身就在批處理檔案的末尾的話,我們是可以省略這句話的,比如將此例的goto :eof刪除是不會產生任何影響的。
【 2、間接傳遞 】
間接傳遞引數,即在使用call命令時,在其後面新增引數,形如call {[:label][ChildBatch]} Parameter1 Parameter2 ... ParameterN。這跟C語言裡面傳遞引數的格式類似。不同於C語言,批處理中的子函式不需要定義形參,更不需要指定引數的個數。傳遞過來的引數,在子函式或子批處理裡面是以%1~%9的形式表示的,即%1~%9分別表示傳遞過來的第1~9個引數。
===============================================
@echo off
call :deal aaa bbb "c c" ddd eee
pause>nul
exit
:deal
echo %%0 = %0
echo %%1 = %1
echo %%2 = %2
echo %%3 = %3
echo %%4 = %4
echo %%5 = %5
===============================================
通過這個例子就可以清晰的看到%n引數表示法的用法。引數列表中包含空格的依舊要用雙引號(")引起來;另外,也可以看到,%0已經變成了子函式的標號了,而不是父批處理的檔名全稱。
【 3、區別 】
這兩種引數傳遞方法本質上是沒有區別的,形式上,直接傳遞直接對原變數進行操作,丟失了原變數的值;間接傳遞則通過%n對原變數進行了簡單的備份,並且通用性更強,即不限定原變數的名稱。另外,使用%n還有一個非常大的好處,就是可以通過%~*i來加強處理變數的能力。關於%~*i,詳細內容參見for /?。
針對二者的差別,可以根據情況決定使用哪種傳遞方式:
--1、作為引數的變數名固定、且在子函式中不需要對其進行備份的情況下,使用直接傳遞法;
--2、若將子函式作為一個通用的程式模組,以適應於對不同變數的處理,或者作為引數的變數不需要備份時,使用間接傳遞法。
具體使用哪種方法,還需根據實際情況或使用習慣進行選擇。
【(三)返回值 】
有些命令在執行之後將會返回一定的錯誤值(errorlevel),可以通過errorlevel的值判斷命令執行的狀況。這點類似於C語言裡面的exit(num),num就是錯誤程式碼。
獲取返回值errorlevel的方法就是,在執行命令後,立馬呼叫返回值errorlevel,如echo %errorlevel%或者if %errorlevel%==1等命令。
errorlevel舉例:
===============================================
@echo off
reg add HKCU /v try /f>nul
reg delete HKCU /v try /f
if errorlevel 0 (echo 刪除成功!) else (echo 刪除失敗!)
reg delete HKCU /v try /f
if %errorlevel%==0 (echo 刪除成功!) else (echo 刪除失敗!)
pause>nul
===============================================
上面例子中,由於第一成功的刪除了登錄檔,導致第二次因為找不到登錄檔而宣告失敗。同時我們也看到了errorlevel的使用方法,即if errorlevel 0和if %errorlevel%==0是一樣的。也許你注意到了,裡面還有個笑臉呢~O(∩_∩)O哈哈~這就是ASCII碼啦,後面跟你講啊…
一般情況下,程式或命令成功執行時,返回的errorlevel是0,錯誤時返回1或更高的值。當然,有些命令是沒有返回值的,這點需要注意。
嗯,有沒有想起前面有個類似的東西啊?對了,那就是||和&&了,這兩個符號就是根據errorlevel的值來進行邏輯判斷的~
【(四)使用者互動 】
批處理,黑框白字是它最著名的特徵。雖然當初DOS為人們使用計算機做出了莫大的貢獻,但在Windows盛行的今天,人們已經疏遠並且懼怕那個黑色的視窗了。微軟為了讓先天有著批量處理“體力活”能力的DOS避免“冷酷”,便於接近,特意提供了幾個小命令,加強批處理的使用者互動功能。
【 1、視窗 】
首先我們要DIY它的視窗。使用命令:color、mode、msg。
--1、設定視窗背景色和字型顏色by color。詳細內容參見color /?。
--2、設定視窗大小by "MODE CON [COLS=c] [LINES=n]",cols即寬度,lines即高度。
--3、GUI互動視窗by msg。詳細內容參見msg /?。
視窗DIY舉例:
===============================================
@echo off
set a=10
set b=0
:tex
set /a a+=3
set /a b+=1
mode con cols=%a% lines=%b%
if %a% lss 60 goto :tex
echo O(∩_∩)O 聖誕快樂 O(∩_∩)O
set a=15,a6,2e,d0,34,8b,4f,9d,5e
for %%i in (%a%) do (
ping -n 2 127.1>nul
color %%i
)
for %%i in (%a%,%a%) do (
ping -n 1 127.1>nul
color %%i
)
>>ms.txt echo */. . . * .
>>ms.txt echo ./* . [] * __
>>ms.txt echo */ . .//~~~~~~~~~~~~'/. ^|◆
>>ms.txt echo /* ,/,..,/,...........,/.◆
>>ms.txt echo ^|^| ..▎# ▎田 田 ▎ ^| ▎◆
>>ms.txt echo ^|^| ^&^&▎ ▎ ▎'^|'▎ o
>>ms.txt echo ^|^| ##■■■■■■■■■■〓
msg %username% /w /time:3600 <ms.txt
del ms.txt
pause
===============================================
【 2、聲音 】
呵呵,是不是注意到了批處理沒有聲音吶?閒話不說,直接做實驗吧 ^_^
===============================================
@echo off
echo 做好準備,響了啊!!
pause
cls
echo
echo 怎麼樣?呵呵,刺激吧~
pause
cls
mshta vbscript:createobject("sapi.spvoice").speak("Merry Christmas and Happy New Year!")(window.close)
pause
===============================================
speak好像不能講中文吶~
■●●●●
此處錯誤,如果tts安裝了中文引擎是可以講中文的。
此外,這個就是呼叫vbs的方法:vbscript:createobject("sapi.spvoice").speak("Merry Christmas and Happy New Year!")
●●●●■
【 3、控制 】
在執行批處理的過程中,我們如何幹預批處理呢?呵呵,直接點叉叉就可以結束它了!嗯,不錯,不過,太野蠻了~
--1、暫停批處理:直接按鍵盤上的Pause鍵嘍
--2、終止批處理:組合鍵Ctrl+C。不過,有時候它好像響應的不太積極啊…
【(五)ASCII碼 】
前面的例子中,我們已經使用過一次ASCII碼了,也就是那個笑臉。ASCII碼是圖形化的符號,可以用來點綴我們的批處理的。
在cmd視窗中我們可以通過任意一個字元的ASCII碼來輸入該字元,比如Ctrl+G、Ctrl+N等,字母a-z對應ASCII碼的1-26。對於ASCII碼大於26的字元,可以通過這個方法來輸入:按住Alt鍵不鬆,通過小鍵盤輸入ASCII碼的十進位制值,鬆開Alt鍵即可。
【(一)環境變數 】
所謂“環境變數”,實際上就是C語言裡面的“變數”的意思。批處理的變數可以分為兩類,由系統定義的系統變數和由使用者根據需要自定義的使用者變數。
【 1、系統變數 】
批處理的一些變數是由作業系統事先定義好的,可以適用於任何批處理,我們稱這些特殊的變數為“系統變數”。系統變數有很多個,包括硬體類、作業系統類、檔案路徑類、系統時間類等。要檢視所有的系統變數,請新開啟一個cmd視窗,輸入set回車即可。對幾個比較常用的變數解釋如下:
ComputerName 計算機名,即右鍵 我的電腦--屬性--計算機名 選項卡中的“完整的計算機名稱”
ComSpec cmd.exe完整路徑名
HomeDrive 系統分割槽碟符,一般都是C盤,故而HomeDrive=C:
Path 可執行檔案預設搜尋路徑。這個東東非常重要!待會兒單獨講解…
ProgramFiles 就是系統的Program Files的路徑啦,一般都是C:/Program Files,這就是安裝軟體時預設的安裝路徑了
Prompt 個性化設定cmd提示符的必備武器!不過,我沒怎麼用過~
SystemDrive 包含系統根目錄的分割槽,其實就是HomeDrive了
SystemRoot 系統根目錄路徑,一般都是C:/WINDOWS
Temp、Tmp 檔案、程式等可使用的臨時目錄,預設是C:/WINDOWS/Temp或Tmp。幾乎所有的程式在執行時都會在這個目錄裡面“臨時”寫入檔案。一般情況下,程式寫入的臨時檔案都應該被該程式刪除,可惜的是,大部分的程式都很健忘,導致這個資料夾佔據的空間越來越大,自然也就使我們的系統增肥嘍。所以,我們要把它修改到其他分割槽,並且時時的清理裡面的臨時檔案。
UserName 當前使用者名稱,即所登陸的賬戶名
UserProfile 當前使用者的配置目錄,一般都是C:/Documents and Settings/%UserName%。預設情況下,我們的桌面就是這個目錄下面的“桌面”資料夾;我的文件就是這個目錄下面的“My Documents”資料夾。所以啦,往桌面上或我的文件裡面放東西就是放到這個資料夾下面了,也就是放到C盤了,重灌系統時要覆蓋C盤內容的,所以桌面上或我的文件裡面的東西當然就會Gone with the Wind了~解決方法有兩個,一是保持良好的習慣,不把重要檔案放到這兩個地方;二是,修改預設設定,將這兩個資料夾都移到其他分割槽。
WinDir 作業系統路徑,其實就是SystemRoot了
【 2、使用者變數 】
編寫批處理程式時,使用者根據需要自己定義的變數稱之為使用者變數。使用者變數類似於C語言裡面的變數,僅僅在定義該變數的程式中有效。
使用者變數由set命令定義,這是批處理中非常非常重要的一個操作,從而使set命令成為批處理裡面使用頻率最高的幾個命令之一。關於set命令的使用,參考set /?,本教程也會在後面對其進行講解。
【 3、變數引用 】
前面的幾節課裡面,我們已經看到了如何引用變數,即直接用變數名操作變數,通過"%"或"!"來獲取變數的值。其中,只有在for語句裡面重複對同一變數多次賦值時才需要使用"!",並且在使用"!"呼叫變數時,要首先“啟用延遲環境變數擴充”,啟動命令為:SetLocal EnableDelayedExpansion。另外需要說明的是,“啟用延遲環境變數擴充”後,所有的"!"都將被視為“取變數值”的特殊符號,即使用"^!"也不能輸出符號"!"。若要輸出"!",則需要“停用延遲環境變數擴充”,命令為:SetLocal DisableDelayedExpansion
【(二)引數 】
跟C語言類似,在呼叫函式或其他批處理時可能需要傳遞引數。批處理的引數傳遞分為直接和間接兩種傳遞引數的方法。
【 1、直接傳遞 】
直接傳遞引數,即在使用call命令時,不使用任何引數,在子函式或子批處理裡面直接對主函式(也稱父批處理)裡面的變數進行修改。這跟組合語言裡面的引數傳遞方式類似。
直接傳遞引數舉例:
===============================================
@echo off
setlocal enabledelayedexpansion
set var=aCdehiM,?mnrstW y
echo %var%
call :deal
setlocal disabledelayedexpansion
set var=%var:?=!%
echo %var%
pause>nul
exit
:deal
set tm=!var!
set var=
for %%i in (6,3,11,11,16,15,1,4,11,5,12,13,9,0,12,7,15,14,5,10,2,16,18,8) do (
set var=!var!!tm:~%%i,1!
)
goto :eof
===============================================
可以發現,當我們把變數var作為引數賦予子函式:deal後,子函式對var的值進行了修改;當子函式返回後,主函式裡面的var的值就已經是子函式裡面var被修改後的值了。
該例子中,使用了本節課前面講到的setlocal enabledelayedexpansion和setlocal disabledelayedexpansion,前者保證了var在for迴圈裡面能夠根據我們的意願進行處理,後者保證了能夠正確輸出符號"!"。另外例子中還使用了命令set,利用set對字串進行了處理。還有一個地方使用了語句goto :eof,該語句相當於C語言裡面的return或組合語言裡面的RET,即子程式返回命令。需要說明的是,當子函式本身就在批處理檔案的末尾的話,我們是可以省略這句話的,比如將此例的goto :eof刪除是不會產生任何影響的。
【 2、間接傳遞 】
間接傳遞引數,即在使用call命令時,在其後面新增引數,形如call {[:label][ChildBatch]} Parameter1 Parameter2 ... ParameterN。這跟C語言裡面傳遞引數的格式類似。不同於C語言,批處理中的子函式不需要定義形參,更不需要指定引數的個數。傳遞過來的引數,在子函式或子批處理裡面是以%1~%9的形式表示的,即%1~%9分別表示傳遞過來的第1~9個引數。
===============================================
@echo off
call :deal aaa bbb "c c" ddd eee
pause>nul
exit
:deal
echo %%0 = %0
echo %%1 = %1
echo %%2 = %2
echo %%3 = %3
echo %%4 = %4
echo %%5 = %5
===============================================
通過這個例子就可以清晰的看到%n引數表示法的用法。引數列表中包含空格的依舊要用雙引號(")引起來;另外,也可以看到,%0已經變成了子函式的標號了,而不是父批處理的檔名全稱。
【 3、區別 】
這兩種引數傳遞方法本質上是沒有區別的,形式上,直接傳遞直接對原變數進行操作,丟失了原變數的值;間接傳遞則通過%n對原變數進行了簡單的備份,並且通用性更強,即不限定原變數的名稱。另外,使用%n還有一個非常大的好處,就是可以通過%~*i來加強處理變數的能力。關於%~*i,詳細內容參見for /?。
針對二者的差別,可以根據情況決定使用哪種傳遞方式:
--1、作為引數的變數名固定、且在子函式中不需要對其進行備份的情況下,使用直接傳遞法;
--2、若將子函式作為一個通用的程式模組,以適應於對不同變數的處理,或者作為引數的變數不需要備份時,使用間接傳遞法。
具體使用哪種方法,還需根據實際情況或使用習慣進行選擇。
【(三)返回值 】
有些命令在執行之後將會返回一定的錯誤值(errorlevel),可以通過errorlevel的值判斷命令執行的狀況。這點類似於C語言裡面的exit(num),num就是錯誤程式碼。
獲取返回值errorlevel的方法就是,在執行命令後,立馬呼叫返回值errorlevel,如echo %errorlevel%或者if %errorlevel%==1等命令。
errorlevel舉例:
===============================================
@echo off
reg add HKCU /v try /f>nul
reg delete HKCU /v try /f
if errorlevel 0 (echo 刪除成功!) else (echo 刪除失敗!)
reg delete HKCU /v try /f
if %errorlevel%==0 (echo 刪除成功!) else (echo 刪除失敗!)
pause>nul
===============================================
上面例子中,由於第一成功的刪除了登錄檔,導致第二次因為找不到登錄檔而宣告失敗。同時我們也看到了errorlevel的使用方法,即if errorlevel 0和if %errorlevel%==0是一樣的。也許你注意到了,裡面還有個笑臉呢~O(∩_∩)O哈哈~這就是ASCII碼啦,後面跟你講啊…
一般情況下,程式或命令成功執行時,返回的errorlevel是0,錯誤時返回1或更高的值。當然,有些命令是沒有返回值的,這點需要注意。
嗯,有沒有想起前面有個類似的東西啊?對了,那就是||和&&了,這兩個符號就是根據errorlevel的值來進行邏輯判斷的~
【(四)使用者互動 】
批處理,黑框白字是它最著名的特徵。雖然當初DOS為人們使用計算機做出了莫大的貢獻,但在Windows盛行的今天,人們已經疏遠並且懼怕那個黑色的視窗了。微軟為了讓先天有著批量處理“體力活”能力的DOS避免“冷酷”,便於接近,特意提供了幾個小命令,加強批處理的使用者互動功能。
【 1、視窗 】
首先我們要DIY它的視窗。使用命令:color、mode、msg。
--1、設定視窗背景色和字型顏色by color。詳細內容參見color /?。
--2、設定視窗大小by "MODE CON [COLS=c] [LINES=n]",cols即寬度,lines即高度。
--3、GUI互動視窗by msg。詳細內容參見msg /?。
視窗DIY舉例:
===============================================
@echo off
set a=10
set b=0
:tex
set /a a+=3
set /a b+=1
mode con cols=%a% lines=%b%
if %a% lss 60 goto :tex
echo O(∩_∩)O 聖誕快樂 O(∩_∩)O
set a=15,a6,2e,d0,34,8b,4f,9d,5e
for %%i in (%a%) do (
ping -n 2 127.1>nul
color %%i
)
for %%i in (%a%,%a%) do (
ping -n 1 127.1>nul
color %%i
)
>>ms.txt echo */. . . * .
>>ms.txt echo ./* . [] * __
>>ms.txt echo */ . .//~~~~~~~~~~~~'/. ^|◆
>>ms.txt echo /* ,/,..,/,...........,/.◆
>>ms.txt echo ^|^| ..▎# ▎田 田 ▎ ^| ▎◆
>>ms.txt echo ^|^| ^&^&▎ ▎ ▎'^|'▎ o
>>ms.txt echo ^|^| ##■■■■■■■■■■〓
msg %username% /w /time:3600 <ms.txt
del ms.txt
pause
===============================================
【 2、聲音 】
呵呵,是不是注意到了批處理沒有聲音吶?閒話不說,直接做實驗吧 ^_^
===============================================
@echo off
echo 做好準備,響了啊!!
pause
cls
echo
echo 怎麼樣?呵呵,刺激吧~
pause
cls
mshta vbscript:createobject("sapi.spvoice").speak("Merry Christmas and Happy New Year!")(window.close)
pause
===============================================
speak好像不能講中文吶~
■●●●●
此處錯誤,如果tts安裝了中文引擎是可以講中文的。
此外,這個就是呼叫vbs的方法:vbscript:createobject("sapi.spvoice").speak("Merry Christmas and Happy New Year!")
●●●●■
【 3、控制 】
在執行批處理的過程中,我們如何幹預批處理呢?呵呵,直接點叉叉就可以結束它了!嗯,不錯,不過,太野蠻了~
--1、暫停批處理:直接按鍵盤上的Pause鍵嘍
--2、終止批處理:組合鍵Ctrl+C。不過,有時候它好像響應的不太積極啊…
【(五)ASCII碼 】
前面的例子中,我們已經使用過一次ASCII碼了,也就是那個笑臉。ASCII碼是圖形化的符號,可以用來點綴我們的批處理的。
在cmd視窗中我們可以通過任意一個字元的ASCII碼來輸入該字元,比如Ctrl+G、Ctrl+N等,字母a-z對應ASCII碼的1-26。對於ASCII碼大於26的字元,可以通過這個方法來輸入:按住Alt鍵不鬆,通過小鍵盤輸入ASCII碼的十進位制值,鬆開Alt鍵即可。