1. 程式人生 > >Windows批處理bat基礎知識總結

Windows批處理bat基礎知識總結

bat基礎知識

編者按:這兩天在寫bat指令碼,這是一個痛苦的週末,來個bat的基礎知識,留著以後慢慢學。

預定義的變數

下面是些已經被底層定義好可以直接使用的變數:不會出現在 SET 顯示的變數列表中
%CD% – 擴充套件到當前目錄字串。
%DATE% – 用跟 DATE 命令同樣的格式擴充套件到當前日期。
%TIME% – 用跟 TIME 命令同樣的格式擴充套件到當前時間。
%RANDOM% – 擴充套件到 0 和 32767 之間的任意十進位制數字。
%ERRORLEVEL% – 擴充套件到當前 ERRORLEVEL 數值。
%CMDEXTVERSION% – 擴充套件到當前命令處理器副檔名版本號。
%CMDCMDLINE%

 – 擴充套件到呼叫命令處理器的原始命令列。
%0 bat的完整路徑名如”C:\Windows\system32\xxx.bat”
%1 bat引數1依次類推%2引數2…
%path% – 當前的環境變數。以分號隔開的路徑列表,路徑可包含空格,可以以’\’結尾, 可以以雙引號包圍之。

引數%0具有特殊的功能,可以呼叫批處理自身,以達到批處理本身迴圈的目的,也可以複製檔案自身等等。

例:最簡單的複製檔案自身的方法

copy %0 d:\wind.bat

擴充套件變數

@ 與%i相關的變數(bat引數或者for迴圈的%i)
假設檔案為C:\Documents and Settings\jinsun\桌面\ParseSinglePkgs.bat
%0

        C:\Documents and Settings\jinsun\桌面\ParseSinglePkgs.bat
%~dp0  C:\Documents and Settings\jinsun\桌面\
%cd%   C:\Documents and Settings\jinsun\桌面
%~nx0   ParseSinglePkgs.bat
%~n0     ParseSinglePkgs
%~x0     .bat

@ 與%VAR%相關的變數

%VAR:str1=str2%   會將VAR中的str1替換為str2(str2如果為空則可以達到刪除的效果,str1前可以加*,變數%ABC:*B=%是C)
%VAR:~0,-2%

          會提取VAR 變數的所有字元,除了最後兩個
%VAR:~2%              會提取VAR 變數的除前兩個的所有字元
%VAR:~-2%             會提取VAR 變數的最後兩個
%VAR:~2,5%           提取從第2個字元開始的5個字元

在bat檔案中,多個命令寫在一行或括號內,如果使用行內或括號內定義或修改的變數,需要啟用延遲變數擴充,用歎號引用變數

bat檔案中用 setlocal enabledelayedexpansion 啟用延遲變數擴充,命令提示符視窗啟用延遲變數擴充,用 cmd /v:on

ren命令中的檔名最好加引號,防止檔名包含空格等特殊字元造成的錯誤。

cd /d %~dp0

批處理檔案中的一條語句
意思是 更改當前目錄為批處理本身的目錄

比如你有個批處理a.bat在D:\qq資料夾下
a.bat內容為
cd /d %~dp0
在這裡
cd /d 表示直接轉換到後面的路徑,否則如果切換碟符,就需要再輸入碟符才能切換路徑
cd /d %~dp0的意思就是cd /d d:\qq
%0代表批處理本身 d:\qq\a.bat
~dp是變數擴充
d既是擴充到分割槽號 d:
p就是擴充到路徑 \qq
dp就是擴充到分割槽號路徑 d:\qq

%0代指批處理檔案自身

%~d0 是指批處理所在的碟符
%~dp0 是碟符加路徑
cd %~dp0 就是進入批處理所在目錄了

%cd%

%cd%代表當前執行批處理檔案的路徑(當前路徑)

echo %cd%

%CD%  當前檔案目錄,不顯示檔名,切通過其找到其他檔案

%0    當前檔案本身,包含完整路徑名和檔名

如 “C:\Windows\system32\xxx.bat”,是一個路徑字串,有引號

*.*  代表所有檔案

>和>>它們的作用都是改變各種提示資訊的輸出方向,把提示資訊輸出到指定的地方去——各種提示資訊預設是輸出到螢幕上去的。

單個的>表示以覆蓋方式重定向提示資訊,也就是說如果目的地原來有內容,將把原來的內容清除掉,用新內容填充;

>>表示以追加的方式重定向提示資訊,也就是說,如果目的地原來有內容,原有的內容將保持不變,在原有內容之後追加新內容。

例如:假設d:\test.txt中的內容是:I Love batch。那麼,在cmd視窗中,分別使用如下兩條語句:echo me,too>d:\test.txt和echo me,too>>d:\test.txt,將會發現,使用第一條語句之後,test.txt中只有一行內容:me,too,而使用第二條語句之後,test.txt中將有兩行內容,分別是I Love batch和me,too。

例如:tree /?>help.txt,這條命令語句就把 tree 命令的幫助資訊重定向到了help.txt檔案中,

help>nul 就把 help 命令的提示資訊重定向到了空裝置中去(nul表示空裝置)。

|   命令管道符

格式:第一條命令 | 第二條命令 [| 第三條命令…]

將第一條命令的結果作為第二條命令的引數來使用,記得在unix中這種方式很常見。

例如:

dir c:\|find “txt”

以上命令是:查詢C:\所有,並發現TXT字串。

md

如果要建立的資料夾帶有空格或&,需要用引號把資料夾名括起來,例如:md “test abc”、md “abc&xyz”。

如果不使用引號,又會帶來什麼後果呢?

1、如果資料夾名帶空格,那麼,md test abc 語句會在當前目錄下建立test和abc這兩個資料夾;利用這個特點,如果要建立abc def xyz這三個資料夾,直接使用 md abc def xyz 就行了,而無需連寫三條md語句。

當然,md abc;def;xyz或者md abc,def,xyz 這樣的寫法也是可以的。

2、如果資料夾名中含有&,那麼,md abc&xyz 會建立abc這個資料夾,並提示說:’xyz’不是內部或外部命令,也不是可執行的程式或批處理檔案,這是因為,&是複合語句的連線符號,它把前後兩部分視為兩條子語句了。

忠告:如果資料夾名含有特殊符號,請不要忘記使用雙引號!

md建立中級目錄。也就是說,md a\b\c這樣的命令,可以在當前目錄下建立資料夾a,然後,在a下建立資料夾b,b之下再建立資料夾c

echo on/off

on 和 off 都是echo 的關鍵字,所謂關鍵字就是系統規定、有特殊用途的字元。

echo on 是打開回顯,echo off 是關閉回顯。

系統預設是echo on,所以每次為了關閉回顯,都會在程式碼的行首加上echo off,加以關閉。

不關閉回顯,連執行的命令符都會顯示出來,所以一般會關閉。

前面加上@又是為什麼?

echo off只能關閉 echo off後面的程式碼的回顯,但不能關閉自身的回顯。所以需要加上@關閉自身。

echo.

echo 後加一點表示換行,真奇葩的設計。

findstr預設是區分大小寫的(跟find命令一樣)

findstr /vm “^teststring” *.txt

findstr /v /m “teststring” *.txt

/i        不區分大小寫 (/ignore)

/V       只打印不包含匹配的行。

/M       如果檔案含有匹配項,只打印其檔名。

啟動一個程式 

call與start區別

start upload.bat

不會等upload.bat執行完再執行下一條, 如此可實現同時執行多條命令.

call upload.bat

call 命令 是要等呼叫的程式結束以後才執行下面的命令.

特殊符號

&:第一條命令 & 第二條命令 [& 第三條命令…]

用這種方法可以同時執行多條命令,而不管命令是否執行成功。

&&:第一條命令 && 第二條命令 [&& 第三條命令…]

當碰到執行出錯的命令後將不執行後面的命令,如果一直沒有出錯則一直執行完所有命令。

||:第一條命令 || 第二條命令 [|| 第三條命令…]

當碰到執行正確的命令後將不執行後面的命令,如果沒有出現正確的命令則一直執行完所有命令;

Sql程式碼  

  1. @echo off
  2. for /? > for.txt
  3. set /? > set.txt
  4. shift /? >shift.txt
  5. exit

執行後在當前路徑下就生成for.txt、set.txt和shift.txt三個檔案,裡面分別記錄了for命令、set命令和shift命令的幫助資訊

1.Echo 命令
打開回顯或關閉請求回顯功能,或顯示訊息。
如果沒有任何引數,echo 命令將顯示當前回顯設定。

語法
echo [{on|off}] [message]
Sample:
@echo off / echo hello world
在實際應用中我們會把這條命令和重定向符號(也稱為管道符號,一般用> >> ^)結合來實現輸入一些命令到特定格式的檔案中.這將在以後的例子中體現出來。

[email protected] 命令
表示不顯示@後面的命令
在入侵過程中(例如使用批處理來格式化敵人的硬碟)自然不能讓對方看到你使用的命令啦。
Sample:@echo off
@echo Now initializing the program,please wait a minite…
@format X: /q/u/autoset (format 這個命令是不可以使用/y這個引數的,可喜的是微軟留了個autoset這個引數給我們,效果和/y是一樣的。)

3.Goto 命令
指定跳轉到標籤,找到標籤後,程式將處理從下一行開始的命令。
語法:goto label (label是引數,指定所要轉向的批處理程式中的行。)
Sample:

Ruby程式碼

  1. if {%1}=={} goto noparms
  2. if {%2}=={} goto noparms(如果這裡的if、%1、%2你不明白的話,先跳過去,後面會有詳細的解釋。)
  3. @Rem check parameters if null show usage
  4. :noparms
  5. echo Usage: monitor.bat ServerIP PortNumber
  6. goto end

標籤的名字可以隨便起,但是最好是有意義的字母啦,字母前加個:用來表示這個字母是標籤,goto命令就是根據這個:來尋找下一步跳到到那裡。最好有一些說明這樣你別人看起來才會理解你的意圖啊。

4.Rem 命令
註釋命令,在C語言中相當與/*——–*/,它並不會被執行,只是起一個註釋的作用,便於別人閱讀和你自己日後修改。
Rem Message
Sample:
@Rem Here is the description.

註釋可以使用Rem,也可以使用雙冒號即::

5.Pause 命令
執行 Pause 命令時,將顯示下面的訊息:
Press any key to continue . . .

Ruby程式碼

  1. @echo off
  2. :begin
  3. copy a:*.* d:\back
  4. echo Please put a new disk into driver A
  5. pause
  6. goto begin

在這個例子中,驅動器 A 中磁碟上的所有檔案均複製到d:\back中。顯示的註釋提示您將另一張磁碟放入驅動器 A 時,pause 命令會使程式掛起,以便您更換磁碟,然後按任意鍵繼續處理。

6.Call 命令

call命令用來從一個批處理指令碼中呼叫另一個批處理指令碼

如果在指令碼或批處理檔案外使用 Call,它將不會在命令列起作用。

語法
call [[Drive:][Path] FileName [BatchParameters]] [:label [arguments]]
引數
[Drive:}[Path] FileName
指定要呼叫的批處理程式的位置和名稱。filename 引數必須具有 .bat 或 .cmd 副檔名。

Ruby程式碼

  1. call mvn clean

7.start 命令
呼叫外部程式,所有的DOS命令和命令列程式都可以由start命令來呼叫。

入侵常用引數:
MIN 開始時視窗最小化
SEPARATE 在分開的空間內開始 16 位 Windows 程式
HIGH 在 HIGH 優先順序類別開始應用程式
REALTIME 在 REALTIME 優先順序類別開始應用程式
WAIT 啟動應用程式並等候它結束
parameters 這些為傳送到命令/程式的引數
執行的應用程式是 32-位 GUI 應用程式時,CMD.EXE 不等應用程式終止就返回命令提示。如果在命令指令碼內執行,該新行為則不會發生。

8.choice 命令
choice 此命令可以讓使用者輸入一個字元,從而執行不同的命令。使用時應該加/c:引數,c:後應寫提示可輸入的字元,之間無空格。它的返回碼為1234……

如: choice /c:dme defrag,mem,end
將顯示
defrag,mem,end[D,M,E]?

Ruby程式碼

  1. @echo off
  2. choice /c:dme defrag,mem,end
  3. if errorlevel 3 goto defrag (應先判斷數值最高的錯誤碼)
  4. if errorlevel 2 goto mem
  5. if errotlevel 1 goto end
  6. :defrag
  7. c:\dos\defrag
  8. goto end
  9. :mem
  10. mem
  11. goto end
  12. :end
  13. echo good bye

此檔案執行後,將顯示 defrag,mem,end[D,M,E]? 使用者可選擇d m e ,然後if語句將作出判斷,d表示執行標號為defrag的程式段,m表示執行標號為mem的程式段,e表示執行標號為end的程式段,每個程式段最後都以goto end將程式跳到end標號處,然後程式將顯示good bye,檔案結束。

9.If 命令
if 表示將判斷是否符合規定的條件,從而決定執行不同的命令。 有三種格式:
1、if “引數” == “字串” 待執行的命令

檢測字串

(注意,用if檢測字串是否相等的時候,後面用的不是“=”,而是“==”)
引數如果等於指定的字串,則條件成立,執行命令,否則執行下一句。(注意是兩個等號)
如if “%1″==”a” format a:
if {%1}=={} goto noparms
if {%2}=={} goto noparms

檢測數值:(注意,批處理中大於符號不能用:“>”,而用”gtr”,其它的也類似)

比較運算子一覽:

EQU – 等於

NEQ – 不等於

LSS – 小於

LEQ – 小於或等於

GTR – 大於

GEQ – 大於或等於

Sql程式碼

  1. @echo off
  2. set /a num1=20
  3. set /a num2=15
  4. if %num1% gtr %num2% echo %num1%大於%num2%
  5. if %num1% EQU %num2% echo %num1%等於%num2%
  6. if %num1% LSS %num2% echo %num1%小於%num2%
  7. pause>nul

、if exist 檔名  待執行的命令
如果有指定的檔案,則條件成立,執行命令,否則執行下一句。
如if exist config.sys edit config.sys

3、if errorlevel / if not errorlevel 數字  待執行的命令
如果返回碼等於指定的數字,則條件成立,執行命令,否則執行下一句。

說明:環境變數errorlevel的初始值為0,當一些命令執行不成功,就會返回一個數值,如:1 ,2 等
如if errorlevel 2 goto x2
DOS程式執行時都會返回一個數字給DOS,稱為錯誤碼errorlevel或稱返回碼,常見的返回碼為0、1。

IF [NOT]  ERRORLEVEL number   do command

IF [NOT]  string1==string2   do command

IF [NOT]  EXIST filename   do command

10.for 命令

for 命令是一個比較複雜的命令,主要用於引數在指定的範圍內迴圈執行命令。
在批處理檔案中使用 FOR 命令時,指定變數請使用 %%variable

在批處理檔案中使用 FOR 命令時,指定變數請使用 %%variable而不要用 %variable。變數名稱是區分大小寫的,所以 %i 不同於 %I

for /f %%i in (a.txt) do echo %%i

//這個會顯示a.txt裡面的內容,因為/f的作用,會讀出a.txt中的內容。

for %%i in (a.txt) do echo %%i

//而這個只會顯示a.txt這個名字,並不會讀取其中的內容。

for %%a in (c:\*.*) do echo %%a

::顯示C盤根目錄下所有非隱藏、非系統屬性檔案

::只顯示檔案,不顯示資料夾

一、/d

(只搜尋目錄,不搜尋檔案)

格式:FOR /D %variable IN (set) DO command [command-parameters]

for /d %%i in (c:/*) do echo %%i  –顯示c盤根目錄下的所有目錄

for /d %%i in (???) do echo %%i   –顯示當前目錄下名字只有1-3個字母的目錄(注意是目錄)

二、/R

(只搜尋檔案,不搜尋目錄)

(搜尋指定路徑及所有子目錄中與set相符合的所有檔案)

格式:FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]

for /r c:/ %%i in (boot.ini) do echo %%i

–枚舉了c盤所有目錄,找到含有boot.ini的路徑並顯示

for /r d:/backup %%i in (1) do echo %%i

–列舉d/backup目錄,現在當前路徑和當前路徑下所有資料夾,不過後面帶了個1

d:\backup\1

for /r c:/ %%i in (boot.ini) do if exist %%i echo %%i

–很好的搜尋命令,列舉boot.ini存在的目錄

三、/L 

(以增量形式從開始到結束的一個數字序列。可以使用負的 Step)

格式:FOR /L %variable IN (start,step,end) DO command [command-parameters]

該集表示以增量形式從開始到結束的一個數字序列。可以使用負的 Step

示例:

for /l %%i in (1,1,5) do @echo %%i  –輸出1 2 3 4 5

for /l %%i in (1,2,10) do @echo %%i  –輸出1,3,5,7,9

for /l %%i in (100,-20,1) do @echo %%i  –輸出100,80,60,40,20

for /l %%i in (1,1,5) do start cmd  –開啟5個CMD視窗

for /l %%i in (1,1,5) do md %%i  –建立從1~5共5個資料夾

for /l %%i in (1,1,5) do rd /q %%i  –刪除從1~5共5個資料夾

setlocal 與 變數延遲

例1:

@echo off

set a=4

set a=5 & echo %a%

pause

結果:4

解說:為什麼是4而不是5呢?在echo之前明明已經把變數a的值改成5了?

(set a=5

echo %a%

::這種情況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

(若不加延遲變數,則會輸出幾個!a!字元)

解說:本例開啟了變數延遲並用“!!”將變數擴起來,因此得到我們預期的結果。如果不用變數延遲會出現什

麼結果呢?結果是這樣的:

ECHO 處於關閉狀態。

ECHO 處於關閉狀態。

ECHO 處於關閉狀態。

ECHO 處於關閉狀態。

ECHO 處於關閉狀態。

即沒有感知到for語句中的動態變化。

文/uule

原文出處——http://uule.iteye.com/blog/2076859