標籤:
1.什麼是Windows BATCH
BATCH也就是批次檔,有時簡稱為BAT,是Windows平台上的一種可運行指令碼,與*nix(Linux和Unix)上的Shell指令碼和其它的指令碼(Perl,Python)等是一樣的,實質上就是一個文字檔,可是用特定的軟體去解釋的時候,就變成了可運行指令碼。在Windows上,可運行指令碼就是BATCH檔案,也叫批次檔,這是從DOS時代遺留下來的名字,意思就是把非常多命令放到一起來運行。它的副檔名是*.bat,雙擊便可直接運行,在命令列(CMD或叫做命令提示字元)以下也能夠當作一個命令來運行。由於這是Windows支援的東西,所以僅僅能在Windows平台使用。(特殊情況除外,不要鑽牛角尖,沒意思的)。比方著名的Windows垃圾清理小工具就是一個BAT批次檔。
2. 為什麼須要BAT
歸根結底是為了提高工作效率。這個解釋起來比較費勁,由於在GUI大行其道的今天,再提命令列,非常多人會不熟悉,或者覺得這是倒退。可是眾多關於提高工作效率的書籍都會提到命令列能夠大大的提高效率,由於命令能夠方便的直接寫路徑,而不用在檔案瀏覽器中一層一層的開啟,和命令列能夠把命令組合起來,也就是把不同的命令組合起來來完畢一個任務,而不用開啟多個GUI表單來做(甚至非常多時候GUI表單都是無法完畢的)。對於這點*nix的程式員們應該最有體會,真正的*nix高手是不會離開命令列的。他們的工作僅僅需開啟一個Terminal(命令列),編輯用Vim,其它全都用命令列的工具來完畢,甚至他們都不用滑鼠!
Windows的CMD沒有*nix的Terminal那麼強大,所以全然在其內做開發有點不切實際,儘管有非常多工具能夠讓CMD變得強大些,可是還是無法達到*nix那樣的地步,由於它們從根本上就是走的不同的路線*nix是為了開發人員準備的,而Windows是為了普通福士準備的。
再說的詳細一點就是為了DRY和Automation,也就是說讓電腦幫你完畢一些機械反覆性的工作任務(對於DRY和Automation能夠參考《The Productive Programmer》和《Pragmatic Programmer》)。由於BAT能夠組合命令,所以某個操作須要超過一個命令,或者參數較多時,或者路徑較長時,就能夠把它寫成BAT,變成一個簡單的命令,一次二個可能沒感覺,可是當天天都用時,就省去了大量的Typing。舉個範例,比方我要常常性的在手機上抓取Tcpdump,然後查看,通常要用到例如以下的命令:
D:\>adb shell tcpdump -p -s 0 -i any -w /sdcard/capture.pcapD:\>adb pull /sdcard/capture.pcap .
然後再用Wireshark去查看這個檔案。假設一個一個的去敲的話,easy寫錯,通常要試幾次才幹成功。可是假設寫一個BAT指令碼的話:
::tcpdump.bat@echo offset dir=/sdcardset file=capture.pcapadb shell rm -r %dir%/%file%adb shell tcpdump -p -s 0 -i any -w %dir%/%file%@echo on::gettcpdump.bat@echo offset dir=/sdcardset file=capture.pcapset wireshark="C:\Program Files\Wireshark\Wireshark.exe"del /q %file%adb remountadb pull %dir%/%file% .%wireshark% %file%@echo on
第一個指令碼tcpdump.bat是抓取,第二個指令碼是查看所抓取的資料,我每次僅僅需執行這二個命令就能夠輕鬆的查看:
D:\>tcpdumpPress Ctrl-C to stop capturingD:\>gettcpdump
之後Wireshark就會把所抓取的資料開啟,直接看即可了。
3. 哪裡能夠用到BAT
不論什麼須要反覆做的事情都能夠嘗試用指令碼來完畢。比方,每天的版本號碼更新,複製檔案,每天都使用的命令等等。如前面所說的,僅僅要某些事情你超過第二次做,或者每天都做幾十次,就應該考慮用BAT。或者,某些命令非常複雜,也要使用BAT,即使把二個簡單命令合成一個BAT也是值得的。比方,調試的時候要查看手機內的資料,就能夠用指令碼來完畢:
::getmmsdb.bat@echo offset datadir=/data/data/com.android.providers.telephony/databasesset mmsdb=mmssms.dbdel /q %mmsdb%adb remountadb pull %datadir%/%mmsdb% .sqlite3 %mmsdb%@echo on
由於BAT中能夠寫不論什麼能夠在CMD命令列中執行的命令,另外,非常多應用程式也提供了命令版本號碼,比方WinRAR,假設你須要從某個地方拷貝東西並解壓,就能夠用BAT:
::copyversion.bat@echo offdel /q stable.rarset winrar="C:\Program Files\WinRAR\WinRAR.exe"copy /y \\192.168.0.1\version\release\stable.rar .%winrar% x stable.rar@echo on
無論怎麼樣,這都比手動去做要來的方便。
另外就是*nix上面的非常多有用命令列程式都有了Windows的版本號碼,比方Subversion,它有一個版本號碼就是專門用於命令列的,所以把所安裝的軟體與內建的一些命令組合起來,能夠創造出非常強大的Automation的工具。
另一點就是第三方工具的拓展,Windows本身的內建命令非常少,可是有第三方的工具來拓展它比方PowerShell等,加之這些工具,能夠讓程式猿的工具箱更加的豐富和強大。
事實上,這裡最關鍵的地方不在BAT,或者你是否會寫這種指令碼,而是在於你是否能意識到BAT指令碼能夠替代手工。能夠讀一讀《The Productive Programmer》和《Pragmatic Programmer》來擷取點靈感。
4. 怎樣使用BAT
BAT是一個可運行指令碼,也就是說它跟一個*.exe可運行程式一樣,僅僅要雙擊它就能夠運行了。另外的方式就是通過CMD在命令列中啟動它,但須要給出它的路徑,也就是說要讓解釋程式能找到它,所以推薦的做法是把所寫的BAT收集整理到一個目錄中,然後把這個檔案放到系統的環境變數PATH中去,這樣就能夠在不論什麼的路徑中使用了。
如,我的配置是這種,把全部的BAT放在D:\work\bin以下,然後把D:\work\bin加到Path變數中去。
加入環境變數的方法是右擊"我的電腦"-->"屬性"-->"進階"-->環境變數-->在使用者變數中編輯Path(假設沒有就新加一個)然後把D:\work\bin加入當中,與其它的路徑用分號;分隔。之後就能夠像執行內建命令一樣來執行它了。(假設你有許可權,也可改動系統變數)。
5. 怎樣寫BAT0. 檔案的編輯
它就是一個文字檔,所以用最簡單的記事本就能夠編輯。當然,你用其它的強大的工具也能夠,比方假設用Vim編輯還能有文法高亮等VIP級待遇。不管用什麼編輯器,一定要注意儲存時一定把要檔案的副檔名記為*.bat,否則就不再是可運行指令碼了,大家都是程式員,你們懂得。
前面提到了,BAT事實上就是把CMD中的命令或其它可運行命令組合到一起,所以BAT的基石是命令,以下重點講下命令。
1. 基本命令及其通用的規則
這裡指的基本命令是指CMD命令中的的內建命令,也就是help命令所顯示的命令,不包含在環境變數中的以及第三方的,那些是外部命令。
主要的命令有檔案操作,目錄操作,時間等等。比方:del, ren, rd, cd, copy, xcopy, time等等。
a. 命令的一般格式
與*nix系統的命令的一樣,它的格式也都是
command [options] [arguments]
當中options是控制和改變命令的行為,每一個選項必須以/開頭,後面跟選項,能夠把多個選項連在一起寫,也能夠用空格格開,每一個選項也能夠跟自己的參數。arguments就是傳遞給命令的參數,也就是要命令所啟動並執行對象。如:
del /f /q /s tmp
這裡/f /q /s就是三個選項/f意思是強制移除,/q是安靜模式,也就是刪除前不提示,/s是刪除子檔案夾;而tmp則是要刪除的對象也就是del命令的參數。
dir /on tmp
這裡的話/on是它的選項,當中/o是選項,意思是排序,而n是選項的參數,合起來就是按名字排序。
通常,一個命令都有預設的選項和參數,也就是說你不指定,也會有。詳細選項不同的命令會有不同的選項。
b. 一些通用的選項:
儘管不同的命令有著不同的參數,可是有一些共同的:
- /? 顯示協助資訊,全部的命令都有(跟*nix的-h一樣)
- /s 對於檔案夾操作來講是包含子檔案夾(跟*nix的-r一樣)
- /q 安靜模式,也就是某些操作不要提示,比方刪除時,或覆蓋檔案時不要提示
c. 擷取協助
不可能記住全部的東西,所以每當遇到一個命令時就要擷取其協助資訊。
help command
或
command /?
就能夠看到command的協助資訊。而直接用help命令,則能夠查看CMD命令列的協助,也就是說它支援哪些內建命令。須要注意的是help僅僅能查看有哪些內建以及顯示內建命令的協助資訊。對於那些在環境變數Path中的命令,它是無法擷取協助資訊的,對於那些命令,僅僅能通過命令本身去找協助資訊。
2. 擴充命令
就是CMD命令列非內建的,存在於環境變數Path中的命令,這些命令使用起來跟內部命令無差別,都能夠在CMD中直接調用。這些命令通常都是由第三方或作業系統提供,完畢某些特定領域的功能,比方C:\Windows\System和C:\Windows\System32下的非常多可運行程式,都可做為外部命令來使用,比方你在命令列中直接輸入notepad然後按斷行符號,記事本就會開啟。以及安裝的第三方程式如WinRAR等。
這些程式也許支援命令模式,也許不支援,這個要去參考程式的文檔,另外,即使其支援命令列,選項和參數也要參考文檔。
3. 凝視和@及echo off
在BAT中以二個冒號開頭的一行為凝視,::僅僅能凝視一行,且必須在一行的開頭
如:
:: This is a comment
:: copy a file to somewhere
@與echo off的作用一樣,都是DOS 批處理的一個特殊標記符, 僅用於屏蔽命令列回顯。當中@僅僅能影響當前行,而echo off是關閉,直到echo on把回行顯示開啟。二個主要在BAT指令碼中運用,在命令列中直接用看不出不同。在BAT中每當運行一個命令時,都會在CMD命令中顯示出這個命令,比方:
::mydir.bat
dir /on
這種指令碼在執行時會是這種:
D:\>mydir
D:\>dir /on
(顯示目錄的內容)
為了在運行指令碼時不顯示當前命令,就要用到關閉回行顯示功能@和echo off,所以差點兒每一個BAT都有這二行
@echo off
....
@echo on
在開始指令碼前關閉回行顯示,然後在結束時再開啟。用@的目的是把關閉回行顯示命令的回行顯示也不要顯示出來(抱歉,有點繞)。
為什麼要關閉回行顯示呢?由於回行顯示會跟所運行命令的輸出混全在一起,所以看起來非常不爽,特別是當BAT指令碼的命令比較多時,所以要關閉它。
4. 管道
與*nix一樣,BAT中也能夠使用管道,能夠使用管道來把命令組合起來,比方最常見的使用方式就是:
type logfile.txt | more
以分屏查看。
5. 變數的定義和使用
在BAT中用set命令來定義一個變數,然後用二個百分比符號來引用這個變數,所引用的地方全用所定義的值來全然替換,如:
D:\>set logfile="D:\logs\log.txt"D:\>echo %logfile%D:\logs\log.txt
6. 重新導向
與*nix一樣BAT也支援檔案流重新導向。
- < 重新導向輸入資料流,最經常使用的方式是用檔案取代標準輸入
- > 重新導向輸出資料流,最經常使用的方式是把程式運行結果放到檔案裡
- >> 重新導向輸出資料流,加入模式,也就是說從檔案尾部開始加入,最經常使用的地方是儲存Log用
儘管Windows看起來與*nix相去甚遠(特別是前幾年),可是BAT裡面有著跟*nix和SHELL類似的一些重要的特性(管道和重新導向),所以BAT還是相當強大的,儘管不能跟SHELL比,可是至少能夠協助我們完畢非常多機械反覆的工作。
7. 命令列參數
跟程式設計語言(C, C++, Java, Perl)和SHELL一樣,BAT也支援命令列參數,也就是運行命令時所給的參數。在BAT中用%[1-9]來引用它們,如:
::mytype.bat
@echo off
type %1
type %2
那麼在執行時,
C:\>mytype one.txt two.txt
當中%1就是one.txt,%2就是two.txt
跟C和C++語言一樣,另一個%0能夠用它就是指令碼的名字。
8. start命令
在*nix的SHELL中能夠用command &的形式來在後台執行一個命令,也就是用一個新進程來執行命令,而不堵塞以下的命令。有些時候這個非常實用,比方你想用BAT開啟幾個XLSX檔案,用例如以下指令碼:
::openxls.bat@echo offset excel="C:\Program Files\Microsoft Office\Office12\EXCEL.EXE"%excel% "D:\documents\status.xlsx"%excel% "E:\report\report.xlsx"@echo on
這樣會有問題,執行到開啟第一個檔案時會停在那裡,除非你關掉status.xlsx否則,它會堵塞在那裡,第二個檔案不會執行到。
解決方案就是為每個會堵塞的命令開啟一個新的進程,用start命令:
::openxls.bat@echo offset excel="C:\Program Files\Microsoft Office\Office12\EXCEL.EXE"start %excel% "D:\documents\status.xlsx"start %excel% "E:\report\report.xlsx"@echo on
這種話,二個檔案都會被開啟。
9. BAT的不足之處
前面都在說BAT怎樣強大,可是畢竟Windows沒有像*nix那樣給予命令列的強大支援,它跟SHELL相比還差的非常遠,在運行命令和檔案操作方面可能沒什麼大區別,可是在某些方面它還非常弱:
a. 輸入的處理
儘管能夠用<來重新導向輸入資料流,可是它對輸入的處理非常弱,特別的它沒的讀取的命令(SHELL中的read),它也不能按行讀入檔案。所以當涉及到檔案處理時,它就顯得力不從心了。
b. 文本處理的能力
如上一條說,非常多時候能須要從一個文字檔讀取內容,然後對其做一些處理。這點上面BAT非常弱,跟SHELL是沒法比的。由於SHELL本身有靈活的讀取函數,能夠按行讀,也能夠把一行按不同的單詞來讀,再加上其本身有字串處理函數,還有就是*nix有豐富的字串處理命令如grep, sed, ed, awk等等。當然,如今這些東西也都有了Windows的版本號碼。可是用BAT來處理檔案還是一個相當麻煩的事。
對於文本處理,最好是能用Perl等程式性的指令碼來寫,它在處理輸入,讀取和處理,以及正則表達式上都有非常好的支援。
10. 開機自己主動執行
某些軟體會有內部選項以達到開機自己主動執行,甚至它總是開機自己主動執行,比方著名的QQ,迅雷暴風影音等等。對於我來說這些都是流氓軟體,特別是那些無法取消其開機自己主動執行的,會造成開機時非常卡。
可是我們日常工作都須要開一些固定的軟體,比方郵件client,Eclipse,開啟某個特定的目錄,開啟某個特定的網頁等等。這些正派的軟體反倒沒有“開機自己主動執行”選項,怎麼辦呢?這時BAT就派上大用場了,能夠寫一個叫做startup.bat,在裡面把要執行的程式都寫上,然後在Start Menu的Startup目錄中建一個指向我們startup.bat的捷徑:
:: startup.bat@echo off"C:\WINDOWS\explorer.exe" "C:\Documents and Settings\User\案頭\alex"set ie="C:\Program Files\Internet Explorer\iexplore.exe"set mail="https://webmail.microsoft.com/"start %ie% %mail%start "C:\Program Files\Microsoft Office\Office12\EXCEL.EXE" "D:\documents\report.xlsx"start mstsc d:\work\rdps\linux.RDPstart mstsc d:\work\rdps\windows.RDPddms.batclean.batD:\eclipse-java-galileo-SR2-win32\eclipse.exe@echo on
每一個工具都有其優勢和不足,我們要做的就是用正確的工具去做正確的事,以期達到最高效的工作效率。儘管有Perl等更加強大的工具,儘管有PowerTools等拓展工具。可是當你有環境的限制的時候,比方因為工作環境的限制,你僅僅有一個Windows系統,沒有Perl或PowerTools時,你能用的就僅僅有BAT了。這個時候就要發揮BAT的威力了,複雜的它做不了,可是簡單的它還是能非常好的勝任的。
指令碼,強大也好,局限也罷,是為了協助我們解決一些反覆性的問題的。所以關鍵不在指令碼,而是在於我們要發現日常工作中的反覆性的勞動,然後用指令碼來替代。切記,電腦的反覆性遠比人好,並且電腦就是被設計用來取代人類做一些機械反覆的工作的,這是它的使命,讓它完畢它的使命吧!
參考資料:這幾篇文章介紹的比較具體
基本介紹
”石頭劄記 批次檔“
這二個哥們寫了非常多操作字串的BAT
"DOS -string operations"
"DOS - String Manipulation"
深入淺出Windows BATCH