A. CMD的命令字元
@
\\隱藏命令的回顯。
~
\\在for中表示使用增強的變數擴展;
在set中表示使用擴展環境變數指定位置的字元串;
在set/a中表示按位取反。
%
\\使用兩個%包含一個字元串表示引用環境變數。比如一個%time%可以擴展到當前的系統時間;
單個%緊跟0-9的一個數字表示引用命令行參數;
用於for中表示引用循環變數;
連續的兩個%表示執行時脫為一個%。
^
\\取消轉義字元,即將所有轉義字元的轉義作用關閉。比如要在屏幕顯示一些特殊的字元,比如> >> | ^等時,就可以在其前面加一個^符號來顯示這個^後面的字元了,^^就是顯示一個^,^|就是顯示一個|字元了;
在set/a中是按位異;
在findstr/r的[]中表示不匹配指定的字元集。
&
\\命令連接字元。比如我要在一行文本上同時執行兩個命令,就可以用&命令連接這兩個命令;
在set/a中是按位與。
*
\\代表任意個任意字元,就是我們通常所說的"通配符";比如想在c盤的根目錄查找c盤根目錄里所有的文本文件(.txt),那麼就可以輸入命令"dir c:\*.txt";
在set/a中是乘法。比如"set/a x=4*2",得到的結果是8;
在findstr/r中表示將前一個字元多次匹配。
()
\\命令包含或者是具有優先權的界定符吧,比如for命令要用到這個(),我們還可以在if,echo等命令中見到它的身影;
-
\\范圍表示符,比如日期的查找,for命令里的tokens操作中就可以用到這個字元;
在findstr/r中連接兩個字元表示匹配范圍;
-跟在某些命令的/後表示取反向的開關。
+
\\主要是在命令裡面會用到它,表示將很多個文件合並為一個文件,就要用到這個+字元了;
在set/a中是加法。
|
\\管道符。就是將上一個命令的輸出,作為下一個命令的輸入."dir /a/b | more"就可以逐屏的顯示dir命令所輸出的信息;
在set/a中是按位或;
在幫助文檔中表示其前後兩個開關、選項或參數是二選一的。
:
\\標簽定位符,可以接受goto命令所指向的標簽。比如在批處理文件裡面定義了一個":begin"標簽,用"goto begin"命令就可以轉到":begin"變遷後面來執行批處理命令了。
" "
\\界定符,在表示帶有空格的路徑時常要用""來將路徑括起來,在一些命令裡面也需要" "符號;
在for/f中將表示它們包含的內容當作字元串分析;
在for/f "usebackq"表示它們包含的內容當作文件路徑並分析其文件的內容;
在其它情況下表示其中的內容是一個完整的字元串,其中的>、>>、<、&、|、空格等不再轉義。
/
\\表示其後的字元(串)是命令的功能開關(選項)。比如"dir /s/b/a-d"表示"dir"命令指定的不同的參數;
在set/a中表示除法。
<
\\命令重定向符,將其前面的命令的輸出結果重新定向到其後面的設備中去,後面的設備中的內容被覆蓋。比如可以用"dir > lxmxn.txt"將"dir"命令的結果輸出到"lxmxn.txt"這個文本文件中去;
在findstr/r中表示匹配單詞的右邊界,需要配合轉義字元\使用。
>>
\\命令重定向符。將其前面的命令的輸出結果重新定向到其後面的設備中去,後面設備中的內容沒有被覆蓋。
<
\\將其後面的文件的內容作為其前面命令的輸入。
在findstr/r中表示匹配單詞的左邊界,需要配合轉義字元\使用。
=
\\賦值符號,用於變數的賦值。比如"set a=windows"的意思意思是將"windows"這個字元串賦給變數"a";
在set/a中表示算術運算,比如"set /a x=5-6*5"。
\
\\這個"\"符號在有的情況下,代表的是當前路徑的根目錄.比如當前目錄在c:\windows\system32下,那麼你"dir \"的話,就相當與"dir c:\"
在findstr/r中表示正則轉義字元。
''
在for/f中表示將它們包含的內容當作命令行執行並分析其輸出;
在for/f "usebackq"中表示將它們包含的字元串當作字元串分析。
.
\\
在路徑的\後緊跟或者單獨出現時:
一個.表示當前目錄;
兩個.表示上一級目錄;
在路徑中的文件名中出現時:
最後的一個.表示主文件名與擴展文件名的分隔。
&&
\\連接兩個命令,當&&前的命令成功時,才執行&&後的命令;
||
\\連接兩個命令,當||前的命令失敗時,才執行||後的命令。
$
\\在findstr命令裡面表示一行的結束。
``
在for/f中表示它們所包含的內容當作命令行執行並分析它的輸出。
[]
在幫助文檔表示其中的開關、選項或參數是可選的;
在findstr/r中表示按其中指定的字元集匹配。
?
\\在findstr/r中表示在此位置匹配一個任意字元;
?在路徑中表示在此位置通配任意一個字元;
緊跟在/後表示獲取命令的幫助文檔。
!
\\當啟用變數延遲時,使用!!將變數名擴起來表示對變數值的引用;
在set /a中表示邏輯非。比如set /a a=!0,這時a就表示邏輯1。其他資料: 1、%是個ESCAPE字元,通常將之譯為轉義字元,但也有更形象的譯名脫逸字元、逃逸字元等。也就是說%不僅僅將與其相關的特定字元串轉義並替換為特定字元串,而且自身也會被「脫逸」。而且類似於C語言中的轉義字元"\",雙%會轉義並脫逸為單%,四%則脫為雙%。
2、for本身是一個特殊的命令,類似於一個特化的命令解釋器,因為它的功能實現需要執行多條語句,因此它必須也具有對命令行(特指do後的命令行)分析處理的功能。而command/cmd實現for時自然會借用自身原有的命令行分析模塊,因此for具有二級轉義的特性,for中do後的語句被分兩級分析和解釋,第一級在command/cmd讀入並解釋for命令行時,第二級在for讀入並解釋do命令時,它通常會對同一命令行的進行多次解釋。
然後,我們可以注意到,在do中使用命令行參數變數和環境變數時,不需要雙%,那是因為,這些變數在經過第一級轉義後,被替換成特定的不變的字元串常量,參與for循環的所有執行過程;而替代變數則要求在執行(do後的子命令行中)過程中不斷的動態變化,而這個變化自然仍需要通過脫逸字元來實現,因此使用雙%就是成了必然的選擇。
另外,還需要注意到,在命令行中使用for時不需要雙%,這源於命令解釋器對命令行與批處理的處理方式不同。在早期的DOS版本中,%在命令行中不被視為轉義字元,所以不會被轉義和脫逸,所以當時無法在命令行直接引用環境變數。而使用for時,只需要一個%供for進行轉義和脫逸就夠了。在以後的命令解釋器版本中,加入了命令行轉義的支持(主要是環境變數的支持),但命令行for使用單%的傳統仍然保留了下來。
而 cmd中的變數延遲替換是屬於特殊的情況,但不違背以上的轉義原則,只是for中的環境變數不再是常量了。
rmdir /S /Q %mhnet% 2>NUL 1>NUL 做簡單解釋
這句代碼的大意是指將 %mhnet% 指定的目錄刪除,/s 代表刪除其中的子目錄, /q 表示刪除目錄樹時不提示確認, 1>nul 表示將正確刪除目錄樹的信息禁止輸出,2>nul 表示將刪除過程中的錯誤信息禁止輸出
其中的1與2都是代表某個數據流輸入輸出的地址(NT CMD 稱之為句柄,MSDOS稱之為設備),下表(引自WinXP幫助文檔「使用命令重定向操作符 (Redirection Operators」一節))將列出可用的句柄。
句柄 句柄的數字代號 說明
STDIN 0 鍵盤輸入
STDOUT 1 輸出到命令提示符窗口
STDERR 2 錯誤輸出到命令提示符窗口
UNDEFINED 3-9 這些句柄由應用程序和各個具體工具單獨定義
0 鍵盤輸入
1 輸出到命令提示符窗口
2 錯誤輸出到命令提示符窗口
3-9 這些句柄由應用程序和各個具體工具單獨定義。
2 > nul 表示程序出錯的信息也不顯示。
call attrib -r -h c:\autoexec.bat >nul
這句其實是:
call attrib -r -h c:\autoexec.bat 1 > nul
這些1,2,0等等都是句柄,說白了就是代號,你只要知道1是代表輸出信息,2是代表出錯信息,0是代表鍵盤輸入就行了。
如果有什麼不明白的可以多看看幫助與支持。
命令行對重定向符號出現的位置不做過多限定,只要重定向符號後緊隨「字元設備」即可,故以下語句等效:
echo Hello World> hello.txt
echo Hello> Hello.txt World
echo> Hello.txt Hello World
> hello.txt echo Hello World
在NT系列命令行中,重定向的作用范圍由整個命令行轉變為單個命令語句,受到了命令分隔符&,&&,||和語句塊的制約限制。
echo Message1> msg1.txt & echo Message2> msg2.txt
if "%target%"=="" (echo message to screen ) else (echo message to file> %target%)
綜上所述,>nul 意為將此句命令所產生的標准輸出請求重新定向到空設備中,而因為此設備的緘默特性,即相當於將此語句的輸出信息屏蔽(並非隱藏);而 2>nul 則是將程序執行錯誤時的標准錯誤信息輸出請求重定向後屏蔽。它們聯合使用,即為將此語句所可能產生的所有輸出信息屏蔽。
「重定向」是MSDOS起就存在的命令行特性,負責將指定命令或語句所產生的輸入輸出請求由預設的「控制台」轉交給其它的「設備」來完成,它的啟動標志是「重定向符號」(包括「>,>>,<」三個,其各自意義見[1])出現在句中。
一般的命令行程序輸入輸出請求都通過內部定義三個「埠」(在NT下稱為「句柄」,在DOS下未定義)來完成,分別為標准輸入stdin、標准輸出stdout、標准錯誤stderr。它們通常指向的設備為控制台(console,代碼為CON),其中stdin指向控制台的鍵盤,stdout/stderr指向控制台的監視器。因此,控制台通常即指鍵盤與監視器的聯合體,這是在早期大型機的終端機上所體現出來的概念。其中的stdin可被<重定向,stdout可被>、>>重定向,而stderr在DOS下不可直接重定向,只有通過ctty或其它命令將系統控制權轉交給其它設備的方式,來間接完成。
「設備」是指可控制PC硬體或埠的設備驅動程序或埠代碼,它通常由系統底層或硬體驅動程序實現和支持。比如IO.SYS實現的控制台CON、系統時鍾CLOCK$、未知設備CONFIG$、第一串口AUX、第一並口PRN、所有串口COM1~COM4、所有並口LPT1~LPT3、可用盤符A:-X:以及上文提到的空設備NUL。還有許多其它設備,比如HIMEM.SYS實現的XMSXXXX0,EMM386.EXE實現的EMMXXXX0,IFSHLP.SYS實現的IFS$HLP$等。
在這些設備中,可以處理輸入輸出信息的很少,只有CON、NUL以及連接有輸入輸出硬體(列印機、MODEM等)的串口或並口設備。它們被稱為「字元設備」,而磁碟文件也作為一種特殊的字元設備列選其中,這就大大擴充了重定向的自由度與實用性,以致很多人也將重定向稱為「文件重定向」。
空設備NUL是一個特殊的設備,因為它沒有可控制的PC硬體或埠,而只是一個虛構的的設備或埠,它僅存在於軟體層面。正因為如此,它可以接受所有重定向的輸入輸出請求而不給出任何回應(在NT下不會給出任何輸入信息而結束輸入請求,在DOS下則反復填充127個位元組0後終止響應),這種特性使它很像天文學上的能吞噬一切物質和信息的「黑洞」,也很類似哲學上能顛轉陰陽無中生有的「玄玄之道」。它之所以存在,是因為我們需要一個可以默默無聞地無條件吸納各種冗餘輸出信息或輸入請求的「回收站」,正如「黑洞」就像一個巨大的「宇宙垃圾場」一樣
CMD沒有神經錯亂,是set處理的整數太大了,set使用雙位元組存儲整數,有32位的存貯范圍限制,也就是說它的處理范圍是2^-31~2^31-1,你的磁碟空間超過了這個范圍溢出了。
對此我沒有太好的解決辦法,只有舍棄後三位後除以1049的近似演算法。
for /f "tokens=3" %%a in ('dir /-c c:\^|find "可用位元組"') do set freesize=%%a
set /a freesize=%freesize:~0,-3%/1049>nul
echo Freesize:%freesize%
> 創建一個文件
>> 追加到一個文件後面
@ 前綴字元.表示執行時本行在cmd裡面不顯示, 可以使用 echo off關閉顯示
^ 對特殊符號( > < &)的前導字元. 第一個只是顯示aaa 第二個輸出文件bbb
echo 123456 ^> aaa
echo 1231231 > bbb
() 包含命令
(echo aa & echo bb)
, 和空格一樣的預設分隔符號.
; 注釋,表示後面為注釋
: 標號作用
│ 管道操作
; 符號當命令相同的時候可以將不同的目標用;隔離開來但執行效果不變。如執行過程中發生錯誤則只返回錯誤報告但程序還是會繼續執行
首先, @ 不是一個命令, 而是DOS 批處理的一個特殊標記符, 僅用於屏蔽命令行回顯. 下面是DOS命令行或批處理中可能會見到的一些特殊標記符:
CR(0D) 命令行結束符
Escape(1B) ANSI轉義字元引導符
Space(20) 常用的參數界定符
Tab(09) ; = 不常用的參數界定符
+ COPY命令文件連接符
* ? 文件通配符
"" 字元串界定符
| 命令管道符
< > >> 文件重定向符
@ 命令行回顯屏蔽符
/ 參數開關引導符
: 批處理標簽引導符
% 批處理變數引導符
其次, :: 確實可以起到rem 的注釋作用, 而且更簡潔有效; 但有兩點需要注意:
第一, 除了 :: 之外, 任何以 :開頭的字元行, 在批處理中都被視作標號, 而直接忽略其後的所有內容, 只是為了與正常的標號相區別, 建議使用 goto 所無法識別的標號, 即在 :後緊跟一個非字母數字的一個特殊符號.
第二, 與rem 不同的是, ::後的字元行在執行時不會回顯, 無論是否用echo on打開命令行回顯狀態, 因為命令解釋器不認為他是一個有效的命令行, 就此點來看, rem 在某些場合下將比 :: 更為適用; 另外, rem 可以用於 config.sys 文件中.
也可以使用以下的用法:
if exist command
device 是指DOS系統中已載入的設備, 在win98下通常有:
AUX, PRN, CON, NUL
COM1, COM2, COM3, COM4
LPT1, LPT2, LPT3, LPT4
XMSXXXX0, EMMXXXX0
A: B: C: ...,
CLOCK$, CONFIG$, DblBuff$, IFS$HLP$
具體的內容會因硬軟體環境的不同而略有差異, 使用這些設備名稱時, 需要保證以下三點:
1. 該設備確實存在(由軟體虛擬的設備除外)
2. 該設備驅動程序已載入(aux, prn等標准設備由系統預設定義)
3. 該設備已准備好(主要是指a: b: ..., com1..., lpt1...等)
可通過命令 mem/d | find "device" /i 來檢閱你的系統中所載入的設備
另外, 在DOS系統中, 設備也被認為是一種特殊的文件, 而文件也可以稱作字元設備; 因為設備(device)與文件都是使用句柄(handle)來管理的, 句柄就是名字, 類似於文件名, 只不過句柄不是應用於磁碟管理, 而是應用於內存管理而已, 所謂設備載入也即指在內存中為其分配可引用的句柄.