批處理是Windows自帶的一個腳本引擎,語法簡潔、內置一些功能強大的命令,並且可以與Windows上的其他軟件進行良好的通信。批處理能夠提供一系統自動化處理功能,大幅提高日常工作中的一些瑣碎重複事情的效率。
1. 概念
- 批處理(Batch),顧名思義即是指批量處理。批處理是基於dos命令行,Windows默認內置解釋器cmd.exe的腳本語言。批處理文件默認保存爲.bat或.cmd。
- 批處理是基於Dos命令行,所以批處理是沒有GUI的,是運行在命令提示符終端(Command Prompt Terminal)上的, Command Prompt Terminal也被稱爲Dos Console。
- 批處理文件默認的存儲格式爲ANSI,即使用Windows系統默認的編碼格式。
2. 解釋器
- 批處理大小寫不敏感。
- 批處理解釋器默認是讀取一行代碼,然後解釋執行。
- 批處理解釋器如果讀取到圓括號“(”,則認爲直到下一個對應的“)”爲結束。此方式可以讓批處理解釋器一次解釋執行多條命令。
- CTRL+C退出當前正在執行的批處理。
3. 語法
3.1. 註釋
- 段註釋,主要是利用goto來達到段註釋的效果,如:
goto start
= 可以是多行文本,可以是命令
= 可以包含重定向符號和其他特殊字符
= 只要不包含 :start 這一行,就都是註釋
:start
- 行註釋,推薦前面兩種方式:
3.2. 基礎指令
-
Echo命令,用來輸出後面的信息,後面的信息是字符串也可以是變量。
-
回顯,顯示正在執行的代碼內容。
- 批處理代碼默認是開啓回顯的。
- Echo off是關閉此後代碼的回顯,echo on是開啓此後代碼的回顯。
- @是關閉此行代碼的回顯。如:@echo “Hello, World!”
- @echo off是關閉此行代碼及此後的回顯,@echo on是開啓此行及此後代碼的回顯。
-
Pause,暫停指定,暫停批處理解釋器繼續讀解釋執行代碼。用戶按任何鍵將繼續。
-
Cls,清屏命令,清除當前控制檯顯示的內容。
3.3. 定義變量
- 字符串變量
set variable-name=value
set info=Hello world.
echo %info%
注意:=左右都是字符,如果有空格,空格也屬性字符串的一部分。
使用set設置的環境變量只在當前進程及其繼承進程有效,並且是臨時的,進程關閉重啓之後失效。
- 數字變量
set /A variable-name=value
set /A age=18
echo %age%
注意: 可進行加、減、乘、除、取餘操作。 它們的符號分別是 + - * / % ,set /a 可計算的數值,
單個數值且最終運算結果只能大於或等於-2的31次方,小於2的31次方“。批處理算術只能針對整數。
3.4. 字符串
set toolName=MPTool
set ver=1.0.1
set /A verNo=5
rem 取消字符串變量
set ver=
rem 判斷字符串變量是否取消
if [%ver%]==[] echo "String ver is empty"
rem 字符串連接
set mpVer=%toolName% %ver% %verNo%
rem 字符串轉整型
set val=12345
set /A numeric=%val%
rem 替換字符串
set text=Make America great again
echo %text:America=China%
rem 截取字符串
set info=abcdefghijklmnopqrstuvwxyz0123456789
echo 截取前5個字符:
echo %info:~0,5%
echo 截取最後5個字符:
echo %info:~-5%
echo 截取第一個到倒數第6個字符:
echo %info:~0,-5%
echo 從第4個字符開始,截取5個字符:
echo %info:~3,5%
echo 從倒數第14個字符開始,截取5個字符:
echo %info:~-14,5%
3.5. 數組
批處理並不支持真正的數組,以下操作只是模擬數組、列表。
- 定義數組
set a[0]=3
set a[1]=5
set a[2]=7
- 單個訪問數組
echo %a[0]% %a[1]% %a[2]%
- 遍歷訪問
setlocal enabledelayedexpansion
for /l %%n in (0,1,2) do (
echo ![%%n]! )
- 定義列表
set list = 1 3 5 7 9
- 遍歷訪問
for %%a in (%list%) do (
echo %%a )
3.6. 條件判斷
- 語法
if condition (do some stuff)
if condition (do some stuff) else (do other stuff) - 示例
set name=tom
if %name%==tom (echo yes)
set age=21
if %age%==20 (echo yes) else (echo No)
REM 圓括號內的內容可以換行
- 其他判斷符號
EQU - 等於
NEQ - 不等於
LSS - 小於
LEQ - 小於或等於
GTR - 大於
GEQ - 大於或等於 - 是否定義
if defined name (echo Yes) else (echo No)
- 文件是否存在
if exist C:\set2.txt echo "File exists"
if exist C:\set3.txt (echo "File exists") else (echo "File does not exist")
3.7. 循環
For中的變量在文件本時,需要使用轉義字符%,在控制檯時不需要。
- 遍歷字符串
- 遍歷文件及目錄
- 遍歷文本內容
- 循環
- 變量延遲
for語句只執行後面的一句代碼,如果想寫多句代碼,必須用()。批處理解釋代碼時,是先讀出當前行的代碼並解析,for及之後的代碼也是一次加載並解釋的。這就導致for之後的代碼中的變量設置了並沒有立即生效。如果想要立即生效,需要啓用變量延遲。- setlocal enabledelayedexpansion啓用延遲的環境變量擴展,直到出現匹配的endlocal 命令,無論 setlocal 命令之前的設置如何。
- setlocal disabledelayedexpansion禁用延遲的環境變量擴展,直到出現匹配的 endlocal 命令,無論 setlocal 命令之前的設置如何。
- 示例,求0到100之和。
3.8. 輸入輸出
- STDIN
標準輸入,默認爲鍵盤輸入,標號爲0。在批處理中STDIN被處理成CON。
Rem 以下語句將鍵盤輸入輸出到info.txt文件夾。
Copy con info.txt
REM 和上面語句等價,按CTRL+C結束輸入
Type con>info.txt
- STDOUT
標準輸出,默認輸出到命令提示符窗口,標號爲1。
在批處理中默認的輸出即爲STDOUT,可以省略。
Rem 以下兩句等價,將IP信息從STDOUT轉到文件info.txt中。
Ipconfig >info.txt
Ipconfig 1>info.txt
- STDERR
標準錯誤輸出,默認輸出到命令提示符窗口,標號爲2。
rem 以下命令只能將net的標準輸出記錄在result.log文件中,出錯信息則會輸入到控制檯
net stop myservices >result.log
rem 如果想把錯誤信息輸出到文件
net stop myservices 2>result.log
rem 如果想把正確和錯誤信息都輸出到文件,則需要用重定向即將2重定向到1,這樣兩者都輸出到文件
net stop myservices 1>>result.log 2>&1
- nul
很多命令執行都會輸出一些信息,如pause命令。但是如果我不想顯示輸出的信息,可以將輸入信息輸出定向到nul,即相當於不用輸出。
- set /p
- 獲取用戶輸入
- 不換行輸出
- 獲取用戶輸入
3.9. goto和標籤
Rem goto表示跳轉到指定標籤的位置
Goto XX
Rem XX標籤標記位置
:XX
- 用goto模擬while
:While
If %name% NEQ tom (
Rem do some stuff
Goto while
)
- 用goto模擬函數
:Begin
Set /p a=please enter:
If %a%==2 Goto funcA
If %a%==3 Goto FuncB
Exit
:FuncA
Rem do some stuff
Goto Begin:
:FuncB
Rem do some stuff
Goto Begin:
3.10. Call子程序
- 調用子代碼
CALL :label arguments
:label rem do so stuff
- 調用批處理
call f:\test.bat 1 3
- 獲取參數
call調用子程序可以帶參數,參數默認以%0、%1來獲取,參數可以進行擴展。
3.11. 文件讀寫
- 創建新文件並寫入
- 追加到原文件寫入
- 讀文件
3.12. 組合命令及管道
- &
Usage:第一條命令 & 第二條命令 [& 第三條命令…]
用這種方法可以同時執行多條命令,而不管命令是否執行成功 - &&
Usage:第一條命令 && 第二條命令 [&& 第三條命令…]
用這種方法可以同時執行多條命令,當碰到執行出錯的命令後將不執行後面的命令,如果一直沒有出錯則一直執行完所有命令; - ||
Usage:第一條命令 || 第二條命令 [|| 第三條命令…]
用這種方法可以同時執行多條命令,當碰到執行正確的命令後將不執行後面的命令,如果沒有出現正確的命令則一直執行完所有命令; - |
Usage:第一條命令 | 第二條命令 [| 第三條命令…]
將第一條命令的結果作爲第二條命令的參數來使用,記得在unix中這種方式很常見。 - >,>>
將一條命令或某個程序輸出結果的重定向到特定文件中, > 與 >>的區別在於,>會清除調原有文件中的內
容後寫入指定文件,而>>只會追加內容到指定文件中,而不會改動其中的內容。 - < , >& , <&
< 從文件中而不是從鍵盤中讀入命令輸入。
>& 將一個句柄的輸出寫入到另一個句柄的輸入中。
<& 從一個句柄讀取輸入並將其寫入到另一個句柄輸出中。
3.13. 轉義字符
批處理中有很多特殊的符號有特殊的用途,但是當我們想將這些特殊的符號當作原始的字符來用時,就需要特殊的處理,此時就需要轉義字符^來標識。
- 普通字符串
:: 此時就需要轉義,否則批處理執行錯誤
Echo you ^& me
- 命令字符串
:: dir /ad /b /s “%~dp0”^|sort /r是命令字符串,所以|前必須加^轉義爲字符串
for /f “delims=” %%a in (‘dir /ad /b /s "%~dp0"^|sort /r') do (
rd "%%a">nul 2>nul)
3.14. 退出及退出碼
- 批處理退出exit
EXIT [/B] [exitCode]
REM 退出當前cmd.exe,退出碼爲1.
Exit /B 1 - 批處理退出goto :EOF
Goto :EOF退出到上一個調用,上一個調用可以是另外一個批處理中的call命令,也可以是當前批處理中的Call命令。 - Windows中每一個進程退出都有退出碼。
Win32中有API,exit(exitCode)設置當前進程的退出碼。
Python中也能夠通過os.exit(exitCode)來設置退出碼。
批處理中直接調用exe時,是阻塞的方式,等待exe結束之後,通過變量%errorlevel%獲取。
3.15. 內置命令簡介
- Cd設置當前目錄
- Md創建文件夾
- Rd刪除文件夾
- Ren重命名文件
- Copy拷貝文件
- Del刪除文件
- Dir顯示目錄
- Move移動文件
- ASSOC指定或修改文件類型
- FTYPE顯示修改文件關係類型
- Date/time顯示當前日期和時間
- Attrib設置顯示文件屬性
- Choice選擇判斷
- Mode設置窗口
- Color設置窗口字體背景顏色
- title設置控制標題
3.16. 擴展模塊簡介
批處理的很多功能都通過擴展組件完成的,Windows的組件基本都提供了命令行操作。
- Find/findstr查找文本內容,支持正則表達式。
- Forfiles遍歷文本內容,forfiles只支持ANSI格式的文本。
- Ipconfig獲取IP相關的
- WMIC調用WMIC組件獲取設備信息
- Devcon控制設備安裝驅動等
- Xcopy拷貝文件擴展功能
- Format/diskpart格式化分區有關功能
- Schtasks定時計劃功能
- Netstat配置網絡IP協議等
- REG操作註冊表
- Explorer打開文件夾
- Ping網絡通信
- Shutdown關機命令
- Regsvr32註冊反註冊組件