1. 程式人生 > >bat批處理簡介:Windows自動化之道

bat批處理簡介:Windows自動化之道

重複的工作交給程式碼。

導語

最近在工作中遇到一些純粹重複的工作,最終都通過指令碼方式達到了自動化,大大提高效率。比如之前每次釋出zip包都需要手動編譯lua檔案、替換lua引用為二進位制檔案的引用,選擇對應檔案打zip包,每次都需要幾分鐘,還容易出錯、遺漏,很不geek,通過指令碼後實現了完全自動化:

再比如Android專案中用到了外掛,由於正式打包和本地編譯的gradle指令碼不同,以及Android Studio對模組的編譯支援不夠,導致每次都需要手動修改檔名(如本地開發時build.gradle修改為build.gradle.tmpbuild.gradle.local

修改為build.gradle,正式編包時再修改回去),再copy外掛目錄出去單獨開發除錯,最後在把改動合入工程,終端也需要一個按鈕來啟動外掛,十分繁瑣且容易造成程式碼不同步,通過指令碼可以實現工程內一鍵編譯執行:

由於之前沒有用過bat指令碼,所以做自動化時速度不是很快,因此花了一天時間整理一下bat指令碼的使用要點,只是一個綱領,沒有深入講解,因為我覺得需要的時候去學習細節才是最高效的,但必須瞭解整體框架才能快速定位到需求對應的命令,因此整理了這篇文章。
此外,Windows7已經支援了powershell,其語法更接近bash,比bat不知道靈活到哪裡去了,我為什麼不用powershell呢?主要是目前powershell速度遠沒有cmd快,正好我的自動化任務都比較簡單,如果用powershell可能啟動時間比執行時間還長。
為什麼不用python、perl等指令碼語言?這些指令碼需要環境配置,考慮到這些指令碼工具可能被其他人使用,所以希望開箱即用,而且bat足夠簡單,足夠滿足需求。

PART 1:執行環境

類似於程式語言庫,這些命令是Windows內建的,可以作為指令碼的基本元素,可以在cmd執行,也可以寫入cmd執行。首先介紹最重要的兩個命令:help,/?,利用help可以檢視當前內建的命令:

F:\BatchFileProgramming>help
有關某個命令的詳細資訊,請鍵入 HELP 命令名
ASSOC          顯示或修改副檔名關聯。
ATTRIB         顯示或更改檔案屬性。
BREAK          設定或清除擴充套件式 CTRL+C 檢查。
BCDEDIT        設定啟動資料庫中的屬性以控制啟動載入。
CACLS          顯示或修改檔案的訪問控制列表(ACL)。
CALL
從另一個批處理程式呼叫這一個。 CD 顯示當前目錄的名稱或將其更改。 CHCP 顯示或設定活動內碼表數。 CHDIR 顯示當前目錄的名稱或將其更改。 CHKDSK 檢查磁碟並顯示狀態報告。 CHKNTFS 顯示或修改啟動時間磁碟檢查。 CLS 清除螢幕。 CMD 開啟另一個 Windows 命令解釋程式視窗。 COLOR 設定預設控制檯前景和背景顏色。 ......

利用/?可以詳細的瞭解某個命令:

F:\BatchFileProgramming>call /?
從批處理程式呼叫另一個批處理程式。

CALL [drive:][path]filename [batch-parameters]

  batch-parameters   指定批處理程式所需的命令列資訊。

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

CALL 命令現在將卷標當作 CALL 的目標接受。語法是:

    CALL:label arguments

一個新的批檔案上下文由指定的引數所建立,控制在卷標被指定
後傳遞到語句。您必須通過達到批指令碼檔案末兩次來 "exit" 兩次。
第一次讀到檔案末時,控制會回到 CALL 語句的緊後面。第二次
會退出批指令碼。鍵入 GOTO /?,參看 GOTO :EOF 擴充套件的描述,
此描述允許您從一個批指令碼返回。

另外,批指令碼文字引數參照(%0、%1、等等)已如下改變:
......

有了這兩個命令,我也就不需要像網上那些文章一樣詳細解釋每個命令了,查閱文件即可。這裡列一些常用的,建議優先掌握,較為生僻的在需要時詳細學習即可。
常用命令:

REM,echo,color,title,prompt,cls,date,time,start,exit,call,tree,type,pause,shutdown,at

常用環境變數(Environment variables are special variables that contain its values set by the operating system itself, other applications or by manual):

%CD%,%PATH%,%RANDOM%

檔案和資料夾相關的命令:

dir,mkdir,rmdir,chdir,ren,replace,copy,xcopy,del,pushd,popd,move

網路:

net,ping,telnet,tlntadmn,tracert,ipconfig,hostname,ftp,netstat,nbtstat,arp

如果遇到需要但自己又不知道的,google即可。

PART 2:語法

如果只有這些命令,那麼執行bat和在命令列執行沒什麼區別,最多把命令儲存下來了方便以後執行。bat也支援一些程式語言的特性,雖然簡陋且不夠優雅,但應付簡單的自動化任務基本夠用。我覺得Dennis Ritchie和Brian Kernighan的The C Programming Language,是介紹一門語言的模板,所以這裡也按照該書的結構安排。

型別、變數、操作符

bat沒有型別。set命令很重要,用於賦值,通過%name%引用變數,且變數賦值的=兩邊不能有空格:

C:\Users\vimerzhao\Desktop>set a=1
C:\Users\vimerzhao\Desktop>echo a
a
C:\Users\vimerzhao\Desktop>echo %a%
1

bat對運算子的支援和其他語言大同小異:

operators description
() grouping
!、~、- unary operators
*、/、%、+、- arithmetic operators
<<、>>、<、> logical shift and re directional operators
& bitwise and
^ bitwise exclusive or
| bitwise or
=、*=、/=、%=、+=、-=、&=、^=、|=、<<=、>>= assignment operators
, separator
&& for using multiple commands
|| for executing one from many commands

流程控制

bat可以通過for和goto實現迴圈,通過if實現條件語句。bat通過switch的概念支援不同型別的遍歷,switch和Linux命令的option很像,就是選項,常見的有四個:

switch description
for /d the ‘/d’ switch along with the ‘for’ command is used for looping through several directories
for /r the ‘/r’ switch along with the ‘for’ command is used for looping through directories and sub directories
for /l the ‘/l’ switch along with the ‘for’ command is used for looping through a range of specified numbers
for /f the ‘/f’ switch along with the ‘for’ command is used for looping through a wide variety of files, command and strings

for迴圈最常見的應用就是遍歷資料夾:

C:\Users\vimerzhao\Desktop>@echo off
C:\Users\vimerzhao\Desktop>echo 顯示全部檔案
C:\Users\vimerzhao\Desktop>for %a in (*) do echo %a
001.PNG
002.PNG
...

在bat指令碼中由於%與變數引用衝突,要寫成

for %%a in (*) do echo %%a

此外,可以通過內建的語法對檔案做處理(如顯示完整路徑、檔名、字尾名等):

command description
%~I expands %I removing any surrounding quotes (“)
%~fI expands %I to a fully qualified path name
%~dI expands %I to a drive letter only
%~pI expands %I to a path only
%~nI expands %I to a file name only
%~xI expands %I to a file extension only
%~sI expanded path contains short names only
%~aI expands %I to file attributes of file
%~tI expands %I to date/time of file
%~zI expands %I to size of file
%~$PATH:I searches the directories listed in the PATH environment variable and expands %I to the fully qualified name of the first one found. If the environment variable name is not defined or the file is not found by the search, then this modifier expands to the empty string.
%~dpI expands %I to a drive letter and path only
%~nxI expands %I to a file name and extension only
%~fsI expands %I to a full path name with short names only
%~dp$PATH:I searches the directories listed in the PATH environment variable for %I and expands to thedrive letter and path of the first one found
%~ftzaI expands %I to a DIR like output line

if語句除了支援操作符還支援幾個自定義的關鍵字:

operators meaning
equ equal
neq not equal
lss less than
leq less than or equal
gtr greater than
geq greater than or equal

子程式

最後,bat也支援簡單的子程式呼叫,和彙編很像,通過%n可以獲取引數,從1開始,如以下程式碼:

REM filename: test.bat
@echo off
call :procedure "argument 1"

goto:eof
:procedure
    echo repeat part or modular code
    echo %1
goto:eof

輸出為:

F:\BatchFileProgramming>test.bat
repeat part or modular code
"argument 1"

總結

以上基本都是一些提綱挈領的概述,自己也不算精通每個細節,相信只要心中有整體框架,再加上一點自動化的意識,久而久之自會得心應手。

參考