Perl編程格式指南_第1頁
Perl編程格式指南_第2頁
Perl編程格式指南_第3頁
Perl編程格式指南_第4頁
Perl編程格式指南_第5頁
已閱讀5頁,還剩24頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領

文檔簡介

1、Perl 編程格式指南名稱P5EEx:Blue:perlstyle - P5EE 樣式指導 P5EE 是 Perl 5 Enterprise Environment (企業(yè)型 Perl5 樣式指導)的縮寫。 介紹在P5EE發(fā)行版中,包含的所有代碼和文件都遵循了本文所述的樣式。請注意:這些樣式并不是要抑制你的創(chuàng)造力,而是想要使那些閱讀到你代碼的家伙們的生活變得更容易一些。他也可以用來解決分歧,避免個人間糾紛。 下面的這些約定適用于perl模塊,web程序(CGI/mod_perl)以及命令行程序。當然,這些規(guī)則也在一定程度上適用于用P5EE寫的perl代碼。 注意,這些都是指導性的方針,不是必須

2、遵守的規(guī)則。如果在這里你真的需要違反其中一條的話,無論如何,最好先問問P5EE核心團隊。 另外,本文檔中的大部分,并不是強調(diào)正確的方法就是我們的方法。我們需要有一些約定來讓每個人的生活更容易一些。 如果你有什么問題,可以在P5EE開發(fā)郵件列表中詢問,p5ee. /showlist.cgi?name=p5ee P5EE項目所需文件在下面這些網(wǎng)站上可以找到。 / /pub/p5ee 本文檔將隨時間不斷更新,每份最新的文檔結(jié)尾,都會有歷次版本的變動記錄。 編碼規(guī)則Perl版本我們是在perl5.005_03上編寫所有代碼的。也許有一天我們應該利用以下perl5.6的特性。不管怎樣,所有代碼應該在pe

3、rl5.005_03以及后續(xù)版本上都能運行。P5EE所有的核心代碼都在perl5.005_03和perl5.6.0上測試過,雖然現(xiàn)在P5EE用在perl5.6上比較多。 文檔所有的模塊文檔都應參照模塊模板文件中的POD例子來撰寫,解釋模塊的方法,目的,用途和每個帶有名字,描述,輸入,輸出,受影響因素等信息的公用API。 文檔中,如果需要返回一個數(shù)組或哈希表的引用,要記錄數(shù)組的大?。òㄇ‘?shù)孛枋雒總€元素都是什么)和哈希表中每個鍵的名字。如果是復合數(shù)據(jù)結(jié)構(gòu)的話,盡量描繪出合適的結(jié)構(gòu)。 另外,在文檔中還要記錄出返回數(shù)據(jù)是什么類型的數(shù)值。是整型,還是一段HTML代碼,還是一個布爾值? 所有命令行程序

4、的選項都要使用命令行程序樣本文件中的代碼來記錄。每個有效的方法,switch結(jié)構(gòu)等等都要被記錄,連同方法的描述,目的,程序如何使用。不要嘗試對不同目的的程序使用相同的選項。 對于所有的WEB程序,應當在程序注釋段中說明功能,目的和使用。 任何外部文檔,命令行程序和模塊的文檔都要寫成POD樣式。這樣的話,我們就可以把它們通過多種pod2xxx的轉(zhuǎn)換器轉(zhuǎn)換成各種格式的其他文檔。POD不是一種正規(guī)的標簽語言,它只是一種可以讓文檔非常容易轉(zhuǎn)換成其他格式的方法。如果你有什么問題的話,可以自己看一下Perl自帶的 perlpod幫助頁 或者 詢問我們及其其他懂POD的人。Perl中國推廣組的FPC里面,也

5、有一篇 fayland 所寫的關(guān)于 如何撰寫POD 的文章。 版本分別使用模塊,web程序,命令行程序樣本文件中版本的代碼。模塊中的$VERSION將會反映出CVS的版本。Makefile.PL文件應該包含版本描述,并且還應該不依賴于CVS倉庫中任何一個單獨文件的版本。 同樣,擁有$VERSION的XS模塊也會反映出發(fā)行版的版本,否則每當你對文件做了一點改動,你都需要重新編譯那些已經(jīng)共享的庫。這對于從事開發(fā)工作中的人來講,的確是一種痛苦。 我們的發(fā)行版本號使用tuples模式,第一個數(shù)字是主修訂號,第二個數(shù)字是版本號,第三個數(shù)字是子版本號。Odd-numbered版本號是開發(fā)版本。例如:1.0

6、.0 P5EE 1 的首發(fā)版1.0.1 P5EE 1.0的第二次發(fā)布版1.0.10 P5EE 1.0的第二次發(fā)布版的第一次修正版1.1.0 P5EE 1.1的首發(fā)版2.0.0 P5EE 2 的首發(fā)版版本號后面也可以跟一個連字符和一些文字,來表示特別的版本,或者給出額外的信息。例如 1.1.4-bender 注意,這是一個狂歡版 1.5.0-pre1 注意這不是最后的版本,而是預覽版。 在perl5.6.0中,你可以使用象v2.0.0這樣的版本,但是在前幾版的perl是不允許的。所以要把一個tuple版本號轉(zhuǎn)換成一個用$VERSION表示的版本號字符串,使用正常的整數(shù)來表示主修訂號,三個數(shù)字來做

7、版本號和三個數(shù)字來做子版本號。例如: 1.1.6 - 1.001006 2.0.0 - 2.000000這樣,perl就可以通過大于和小于比較兩個版本字符串。 LinuxForum中有一篇關(guān)于 軟件發(fā)行慣例 的中文譯版:/books/srp/Software-Release-Practice-HOWTO.html 注釋所有的代碼都應該盡可能地具有可讀性。所以,我們的代碼中可以只包含一些對于不明朗內(nèi)容的必要注釋。于是,我們應該使用象$story_count這樣的名字,而不是這么做: # story count my $sc = 0;也許要別人理解代碼需要包含一些整齊的注釋。有時一個簡單的單行注釋

8、就可以解釋后面代碼的用途。另外,我們有時還需要對一個復雜的算法需要每行都要注釋。Kernighan 和 Pike 寫的Practice of Programming中關(guān)于注釋的部分值得一看。 警告和嚴格語法所有代碼都必須使用use strict和打開perl的-w選項來編譯和運行。當然,如果你必須禁止 -w 或 strict 的使用,我們也是沒有意見的。(實際上你真正需要這么做的機會將會很渺茫)。 有一個例外是“使用了未初始化的變量”警告,我們在P5EE.pm中禁掉了它,所以在你的代碼中如何包含了“use P5EE”,那么你就不必擔心這些警告了。 詞匯范疇變量只使用詞匯范疇變量,除了一些特殊的

9、全局變量($VERSION,%ENV,ISA,$!等等)和一些極特殊的情況。把全局變量當成普通變量從來都是不恰當?shù)?,如有必要,使用“use vars”來聲明全局變量,而不是使用our()函數(shù)(our()在perl5.6中有介紹)。 詞匯范疇內(nèi)的變量使用my()來創(chuàng)建。一個全局變量是預先存在的(如果他是一個特殊變量),或者當他被使用的時候就剛剛創(chuàng)建。local()被用來告訴perl為一個變量賦一個臨時值。這應該只用于象$/這樣的特殊變量,或者在特殊的環(huán)境中。如果你必須給某個全局變量賦值的話,那么你最好先考慮考慮是否需要用local()。 local()也可以用于數(shù)組或者哈希表中的元素,盡管這很不

10、常用。 輸出默認情況下不要從模塊中輸入任何東西。你可以自由地在EXPORT_OK中放入任何你想放的東西,這樣你的模塊的使用者就可以明確地請求這些符號。(例如:“use P5EE:Something qw(getFoo setFoo)”),但是不要默認地輸出它們。 傳遞引用參數(shù)方法要獲取或者返回數(shù)組和哈希表的時候最好只使用其引用。注意列表和數(shù)組不是一回事。下面這樣就很好: return($user, $form, $constants);當數(shù)組不確定的時候也許是一個例外。 my return = ($user, $form); push return, $constants if $flag;

11、return return;盡管如此,但是,為了提高代碼的效率和可讀性,我們更趨向于編寫這樣的代碼: if ($flag) return($user, $form, $constants); else return($user, $form); 垃圾收集perl在垃圾收集方面的確作的很好。它會自動清理那些過了生存期的詞匯范疇變量和已經(jīng)沒有引用計數(shù)的對象。如果你使用詞匯范疇的話,通常你不必擔心這個。 然而,有一些粘合的代碼,比如用C編譯的代碼連接到perl,perl也許就不會自動幫你清理了。在這種情況下,你就得自己動手了。如果在那些粘合的代碼中有實現(xiàn)此功能的方法,那么使用這些方法是比較適合的。

12、還有,如果你有一個運行時間會很長的函數(shù),里面有一個巨大的數(shù)據(jù)結(jié)構(gòu)。那么希望你盡可能地在它運行完之后立刻釋放一下內(nèi)存。 my $huge_data_structure = get_huge_data_structure(); do_something_with($huge_data_structure); undef $huge_data_structure;_END_ 和 _DATA_ 和 _PACKAGE_在web程序中不要使用_END_或者_DATA_。它們會與mod_perl沖突。還有,在web程序中_PACKAGE_也許不會返回你期望的值。但它們在模塊中運行良好。 測試模塊應該提供測試

13、代碼,還有如何使用它們的文檔。 STDIN/STDOUT永遠使用P5EE的日志工具來報錯。不要直接打印到STDERR上。也不要直接打印到STDOUT上。除非你需要直接打印到用戶的瀏覽器上。 在命令行程序中,根據(jù)你的需要打印到STDERR或STDOUT上都可以。 文件和Globs為了建立和分析文件路徑,請使用Filel:Spect:Functions 和 File:Basename 模塊。要創(chuàng)建和銷毀路徑,使用File:Path模塊。這在非Unix平臺中比較方便。 my $path = $dir/$file; # 錯 my $path = catfile($dir, $file); # 對 my

14、 $dir = .; # 錯 my $dir = curdir(); # 對 mkdir(/path), mkdir(/path/to), . # 錯 mkdir /path; mkdir /path/to, . # 大錯特錯 mkpath(/path/to/my/dir, 0, 0775); # 對請使用 opendir() 和 readdir() 來代替 glob 操作符(glob(*) 或者 )。注意 glob() 在perl5.6中比以往版本更輕便了,但它還是不十分可靠,每個perl的安裝都可以選擇通過 File:Glob 模塊來用本地的習慣來代替這個默認的。 不要為了任何事而使用向*

15、foo這樣的符號表 globs(和上面提到的 glob 不一樣),除非有必要必須直接操作符號表。其實這從來都是不必要的。 系統(tǒng)調(diào)用永遠都要在系統(tǒng)調(diào)用后檢查返回值。包括 open(),close(),mkdir() 或者其他直接面對系統(tǒng)的對話。perl內(nèi)置的系統(tǒng)調(diào)用都會把錯誤信息返回到$!;模塊中的一些方法可能會將錯誤返回到$或者其他地方,如果你不知道的話就去查模塊的文檔。永遠要這么做,哪怕只是調(diào)用一個 errorLog(),當返回的值不是你期望那樣的時候。 樣式很多樣式的描述都是取自perl樣式man文檔。我們在這里做了一些改動,但讀一讀那些文檔也是個不錯的主意。 術(shù)語P5EE項目的名字叫做“

16、P5EE”,并沒有“P5EE1”或者“P5EE2”,要說明版本的話,使用“P5EE 2.0”或者“P5EE2.0.1”。 函數(shù)與子程序與方法的區(qū)別: *方法應該只用于指向?qū)ο蠓椒ɑ蛘哳惖姆椒?;也就是那些使用面向?qū)ο缶幊痰模谝粋€參數(shù)是對象或者是類的函數(shù)。通常意義上的*子程序,它們不是對象或者類的方法,而是函數(shù)。類中創(chuàng)建和返回對象的方法稱為構(gòu)造器。 名字不要使用一個字符的變量,除非是迭代中的指示變量。也不要使用兩個字符的變量,這和使用一個字符的變量沒區(qū)別。常量全部都大寫;這些是在整個程序中都不會變化的變量。 $Minimum = 10; # 錯 $MAXIMUM = 50; # 對其他變量小寫,

17、用下劃線來連接單詞。這些單詞通常都用名詞(一般都是單數(shù)名詞),除非變量被用來指示某些動作的標記,那么這些變量的名字可以使用描述該動作的動詞(或者是動名詞)。 $thisVar = foo; # 錯 $this_var = foo; # 對 $work_hard = 1; # 對,動詞,布爾類型的標記 $running_fast = 0; # 對,動名詞,布爾類型的標記數(shù)組和哈希應該是復數(shù)的名詞,不管是正常的數(shù)組和哈希還是數(shù)組引用和哈希引用。不要給引用命名為ref或者將其類型加入到名字當中。 stories = (1, 2, 3); # 對 $comment_ref = 4, 5, 6; # 錯

18、 $comments = 4, 5, 6; # 對 $comment = $comments-0; # 對讓名字易理解。不要使用象$sc這樣的名字,你應該用“$story_count”。 方法和函數(shù)(除了那些特殊情況,比如AUTOLOAD)應該由動詞開頭,然后后面跟著完成動作的詞匯。詞組組成的名字應該全部小寫,并用下劃線來連接單詞,為了跟perl樣式指導還有那些CPAN上大部分模塊保持一致。這些方法應該盡可能地描繪出它要執(zhí)行什么,和它要返回什么數(shù)據(jù)。 $obj-getStory(); # 錯 $obj-setStoryByName(); # 又錯了 $obj-getStoryByID(); #

19、 還是錯!這不是Java! $obj-get_story(); # 對 $obj-set_story_by_name(); # 對 $obj-get_story_by_id(); # 對以下劃線開頭的方法和函數(shù)是特殊的:它們在當前文件之外是無法使用的。(也就是private-私有的)。但這不是代碼本身強制要求的,而只是編程人員的習慣而已。 對于大的for循環(huán)結(jié)構(gòu),不要使用$_,而是用具名的變量。不要用$_(或者假想它)除非你非常明確是怎么回事,或者需要它的時候(比如在map()和grep()中)。 for (list) print; # 對;每個人都知道這是什么意思 print uc; # 不

20、好;很少有人知道這個 print uc $_; # 看起來好一些了 注意,如果可能的話,請使用特殊變量_。它是一個占位符,可以傳遞給stat()和文件測試符,它讓重新判斷文件的狀態(tài)變得簡單一些。在下面這個例子中。在每個文件測試中都要使用變量$file。使用_來代替是個不錯的選擇。盡管最后一次測試的文件和你想像的一樣,你還是應該小心一些。 if (-d $file) # $file現(xiàn)在是一個目錄 # . elsif (-l _) # $file現(xiàn)在是一個symlink # . 包的名字應該每個單詞的第一個字母大寫,其余的小寫。 P5EE:Standard # 好 P5EE:Authz # 好 P

21、5EE:MainCode # 好在POD文檔中全部使用小寫。 P5EE:styleguide # 對于文檔來說還不錯為模塊命名應該遵循下面幾條規(guī)則。 所有被p5ee郵件列表廣泛支持的P5EE的服務都應該進入P5EE的包中 命名樣式應該和CPAN上的模塊類似。 選擇命名借鑒CPAN上其他模塊的先例。 選擇命名借鑒J2EE的先例。 那些還沒有確定要作為對象被初始化的包應該用一個形容詞或者概念來作名字(也就是 P5EE:Standard)那些已經(jīng)確定要作為對象被促使化的模塊和類包應該用伴有隱含變化形容詞含義的名詞來作名字(也就是說 P5EE:Authen:Principal)。 縮進代碼檢驗后進入C

22、VS必須不能包含制表符。帶有制表符的代碼片斷不能很好的通過email傳遞,而且不同的人對制表符攔截有不同的設置。如果你想為你的編輯器設置制表符攔截,只要保證它保存文件的時候,把制表符轉(zhuǎn)換為空格就可以了。 一般塊樣式代碼應該縮進4個空格。Emacs和vim的設置如下。 *t .xemacs/custom.el: - (custom-set-variables (cperl-indent-level 4) (cperl-continued-statement-offset 4) (cperl-tab-always-indent t) (indent-tabs-mode nil) ) * vim .

23、vimrc: - set expandtab replaces any tab keypress with the appropriate number of spaces set tabstop=4 sets tabs to 4 spaces 將制表符換成適當數(shù)量的空格 將制表符換成4個空格行的長度行的最長長度應該是77列(對未折行的應該有75列),這是為了最大限度地適用于不同人的開發(fā)環(huán)境和為了更好的用email來傳輸而適應不同的email客戶端。(也為了補?。?例如:Eudora3.0.6 會在第76個字符處,使用一行實心線來限制第80個非空白字符的輸出。如果行中間有空格,則它允許在最后

24、一個詞后自動換行到下一個具有78個字符的行中。如果源文本沒有一行超過77個字符的情況,那么“diff -u”命令則會添加一列,當然這列是不會被折行的。 空白在結(jié)束句子的分號之前不要留空白。 foo(bar) ; # 錯 foo(bar); # 對垂直對齊。 my $foo = 1; my $bar = 2; my $xyzzy = 3; open(FILE, $fh) or die $!; open(FILE2, $fh2) or die $!; $rot13 = trabcedfghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm; # note w

25、e use a-mn-z instead of a-z, # for readability $rot13 = tra-mn-z n-za-m;為了增加可讀性,下列操作時需要一些空白: * 在做不同工作的代碼塊間,添加空行。 * 在變量聲明完成之后,添加空行。 * 在最終的return()代碼之前,添加空行。 * 在塊的前面和后面添加空行,如果前面是注釋的話,則不用添加空行。 一個例子: # this is my function! 這是我的函數(shù) sub foo my (data) = _; my $obj = new Constructor; my ($var1, $var2); $obj-

26、setFoo($data1); $var1 = $obj-getFoo(1); $var2 = $obj-getFoo($var1); display($var1, $var2); return($data0); print 1;圓括號在流程結(jié)構(gòu)中,在關(guān)鍵詞和圓括號對之間要有空格。但對于函數(shù),則不必。 for(list) # 錯 for (list) # 對 my ($ref) # 對 my($ref) # 首選 localtime ($time); # 錯 localtime($time); # 對對帶圓括號的列表和標量上下文要仔細! my array = (a, b, c); my ($f

27、irst_element) = array; # a my ($first_element) = (a, b, c); # a my $element_count = array; # 3 my $last_element = (a, b, c); # c永遠在函數(shù)后面加上圓括號,盡管沒有參數(shù)也是如此。但有一些例外,比如列表操作符(比如print)和一元操作符(像undef,delete,uc等等)。 如果為了可讀性,可以在圓括號中添加空格,否則不要添加。 for ( map $_, 1 list ) # 可以 for ( list ) # 也還可以。在多行的表達式中,用開始的語句或前圓括號來

28、對齊后圓括號都可以。 list = qw( bar baz ); # 正確 if ($foo & $bar & $baz & $buz & $xyzzy ) print $foo; 在后圓括號之后是否添加空格取決于它后面要跟什么。 print foo(bar), baz(buz) if $xyzzy;還要注意,在允許省略圓括號的情況下單行控制流程表達式,比如if $xyzzy,對于程序員來說,如果你十分明確它的含義的話,你可以省略圓括號。其實在上面的這種情況在$xyzzy兩邊是完全可以省略掉圓括號的。所以就省略掉它們,以增加可讀性。如果有問題的話,那最好就別省略圓括號了。 同樣原則也適用于pe

29、rl的內(nèi)置函數(shù),當你很確定的情況下(例如,在語句中只有一句調(diào)用函數(shù)的語句,或者函數(shù)調(diào)用被流控制操作符分割)。用戶自定義函數(shù)必須加上圓括弧。 print 1, 2, 3; # 好的 delete $hashkey if isAnon($uid); # 好的不管怎樣,如果有什么疑惑的情況,最好加上圓括弧,記住perl樣式man文檔中Larry Wall的一句話: 當你有疑惑的時候,加上圓括號,至少,它可以讓一些可憐的笨家伙在vi中能用%跳舞。(在vi中%用來尋找匹配的括號) 盡管你不處于疑惑之中,將來使用你的代碼的人,就算是為他們的大腦神經(jīng)做做公益事業(yè),你還是加上圓括號吧,省得將來他們自己加括號也

30、許會加錯地方。 所以,當程序員非常清楚的情況下,省略圓括號,但是如果有任何問題的話,就不要省略它們。 花括號(這是關(guān)于流程控制中的花括號,不是哈希等數(shù)據(jù)結(jié)構(gòu)中的花括號。) 在前花括號之前一定有一個空格 while () # 錯 while () # 對一行的代碼塊可以寫在一行中。那代碼后面的分號可以省略。 for (list) print 否則,在每一行代碼結(jié)束的地方添加分號,在第一行寫關(guān)鍵字和前花括號,后花括號和后面的關(guān)鍵字寫在一行。 for (list) print; smell(); perl樣式中常用“單臂elses”:(譯者注:就是else旁邊只有一個單花括號。) # 對 if ($

31、foo) print; else die; # 錯 if ($foo) print; else die; 操作符多數(shù)操作符兩邊可以添加空格。主要的例外是從美學角度出發(fā)的;例如,“*”符號兩邊的空格是省略的。另外,在“,”的前面沒有空格,而在后面往往有一個空格。 print $x , $y; # 錯 print $x, $y; # 對 $x = 2 1; # 好 $y = 2*2; # 好注意“&”和“|”的優(yōu)先級高于“and”和“or”。除此之外完全相同。建議使用低優(yōu)先級的來控制流程,高優(yōu)先級的用來測試/返回值。例如: $bool = $flag1 or $flag2; # 錯誤!無法運行 $

32、value = $foo | $bar; # 正確 open(FILE, $file) or die $!; $true = foo($bar) & baz($buz); foo($bar) and baz($buz);注意上面“and”很少使用and,因為上面的語句比用“if”寫要好一些。 baz($buz) if foo($bar);大多數(shù)情況下,and和&,or和|之間的混淆可以通過使用圓括號很好地解決。如果你不使用圓括號,那么你必須正確使用操作符。但如果你使用了圓括號通常,如果有問題的話,應該使用那么不管你用什么操作符都關(guān)系不大。從易讀角度來看也好,從美學角度來看也好,一定要在你的代碼

33、塊中保持風格一致。 在很長的代碼行中在操作符之后斷行,但“and”,“or”,“&”,“|”例外。對于二元的操作符來講,符號兩邊的數(shù)據(jù)要盡量保持整齊。 print foo . bar . baz . buz; # 錯 print foo . bar . baz . buz; # 對 print $foo unless $x = 3 & $y = 4 & $z = 5; # 錯 print $foo unless $x = 3 & $y = 4 & $z = 5; # 對其他在括號或者花括號中間有復合下標索引時,在兩邊加上空格, $foo$barbazbuz; # 不錯 $foo $barbaz

34、buz ; # 更好總的來說,單引號之間表示是純字符,雙引號之間表示是允許內(nèi)插的文本。 在花括號之間的名稱和當使用=符號的情況下可以省略引號,但是一定要小心這個名稱不要和函數(shù)名重復。如果有重復,則必須使用引號。 $whattimeitis = time();當創(chuàng)造復合語句的時候,把主要的執(zhí)行動作放在前面。 open(FILE, $fh) or die $!; # 對 die $! unless open(FILE, $fh); # 錯 print Startingn if $verbose; # 對 $verbose & print Startingn; # 錯使用“打印至”來代替重復使用pr

35、int語句。 print 只要記住,除非你在“打印至”的記號兩邊寫上單引號(EOT),那么其間的文本是可以內(nèi)插的。所以要打印“$”和“”符號是需要轉(zhuǎn)義的。 附錄資料:不需要的可以自行刪除bat文件的基本應用bat是dos下的批處理文件 .cmd是nt內(nèi)核命令行環(huán)境的另一種批處理文件 從更廣義的角度來看,unix的shell腳本以及其它操作系統(tǒng)甚至應用程序中由外殼進行解釋執(zhí)行的文本,都具有與批處理文件十分相似的作用,而且同樣是由專用解釋器以行為單位解釋執(zhí)行,這種文本形式更通用的稱謂是腳本語言。所以從某個程度分析,batch, unix shell, awk, basic, perl 等腳本語言都

36、是一樣的,只不過應用的范圍和解釋的平臺各有不同而已。甚至有些應用程序仍然沿用批處理這一稱呼,而其內(nèi)容和擴展名與dos的批處理卻又完全不同。 = 首先批處理文件是一個文本文件,這個文件的每一行都是一條DOS命令(大部分時候就好象我們在DOS提示符下執(zhí)行的命令行一樣),你可以使用DOS下的Edit或者Windows的記事本(notepad)等任何文本文件編輯工具創(chuàng)建和修改批處理文件。 = 注 = 批處理文件中完全可以使用非dos命令,甚至可以使用不具有可執(zhí)行特性的普通數(shù)據(jù)性文件,這緣于windows系統(tǒng)這個新型解釋平臺的涉入,使得批處理的應用越來越邊緣化。所以我們討論的批處理應該限定在dos環(huán)境或

37、者命令行環(huán)境中,否則很多觀念和設定都需要做比較大的變動。 = 其次,批處理文件是一種簡單的程序,可以通過條件語句(if)和流程控制語句(goto)來控制命令運行的流程,在批處理中也可以使用循環(huán)語句(for)來循環(huán)執(zhí)行一條命令。當然,批處理文件的編程能力與C語言等編程語句比起來是十分有限的,也是十分不規(guī)范的。批處理的程序語句就是一條條的DOS命令(包括內(nèi)部命令和外部命令),而批處理的能力主要取決于你所使用的命令。 = 注 = 批處理文件(batch file)也可以稱之為批處理程序(batch program),這一點與編譯型語言有所不同,就c語言來說,擴展名為c或者cpp的文件可以稱之為c語言

38、文件或者c語言源代碼,但只有編譯連接后的exe文件才可以稱之為c語言程序。因為批處理文件本身既具有文本的可讀性,又具有程序的可執(zhí)行性,這些稱謂的界限是比較模糊的。 = 第三,每個編寫好的批處理文件都相當于一個DOS的外部命令,你可以把它所在的目錄放到你的DOS搜索路徑(path)中來使得它可以在任意位置運行。一個良好的習慣是在硬盤上建立一個bat或者batch目錄(例如C:BATCH),然后將所有你編寫的批處理文件放到該目錄中,這樣只要在path中設置上c:batch,你就可以在任意位置運行所有你編寫的批處理程序。 = 注 = 純以dos系統(tǒng)而言,可執(zhí)行程序大約可以細分為五類,依照執(zhí)行優(yōu)先級由

39、高到低排列分別是:DOSKEY宏命令(預先駐留內(nèi)存),COMMAND.COM中的內(nèi)部命令(根據(jù)內(nèi)存的環(huán)境隨時進駐內(nèi)存),以com為擴展名的可執(zhí)行程序(由 直接載入內(nèi)存),以exe位擴展名的可執(zhí)行程序(由 重定位后載入內(nèi)存),以bat位擴展名的批處理程序(由 解釋分析,根據(jù)其內(nèi)容按優(yōu)先級順序調(diào)用第2,3,4,5種可執(zhí)行程序,分析一行,執(zhí)行一行,文件本身不載入內(nèi)存) = 第四,在DOS和Win9x/Me系統(tǒng)下,C:盤根目錄下的AUTOEXEC.BAT批處理文件是自動運行批處理文件,每次系統(tǒng)啟動時會自動運行該文件,你可以將系統(tǒng)每次啟動時都要運行的命令放入該文件中,例如設置搜索路徑,調(diào)入鼠標驅(qū)動和磁盤

40、緩存,設置系統(tǒng)環(huán)境變量等。下面是一個運行于Windows 98下的autoexec.bat的示例: ECHO OFF PATH C:WINDOWS;C:WINDOWSCOMMAND;C:UCDOS;C:DOSTools; C:SYSTOOLS;C:WINTOOLS;C:BATCH LH SMARTDRV.EXE /X LH DOSKEY.COM /insert LH CTMOUSE.EXE SET TEMP=D:TEMP SET TMP=D:TEMP = 注 = AUTOEXEC.BAT為DOS系統(tǒng)的自動運行批處理文件,由COMMAND.COM啟動時解釋執(zhí)行; 而在Win9x環(huán)境中,不僅增加支

41、持了 DOSSTART.BAT, WINSTART.BAT 等許多其它自動運行的批處理文件,對AUTOEXEC.BAT 也增加了 .DOS .W40 .BAK .OLD .PWS 等許多變體以適應復雜的環(huán)境和多變的需求。 = willsort 編注 = 以下關(guān)于命令的分類,有很多值得推敲的地方。常用命令中的本不是命令,而dir、copy等也很常用的命令卻沒有列入, 而特殊命令中所有命令對我來說都是常用命令。建議將批處理所引用的命令分為內(nèi)部命令、外部命令、第三方程序三類。而內(nèi)部命令和外部命令中別有一類是專用于或常用于批處理中的命令可稱之為批處理命令。 以下摘錄MS-DOS 6.22 幫助文檔中關(guān)

42、于批處理命令的文字,當然,其中有些概念和定義已經(jīng)有些落后了。 批處理命令 批處理文件或批處理程序是一個包含若干MS-DOS命令的正文文件,擴展名為.BAT。當在命令提示符下敲入批處理程序的名稱時,MS-DOS成組執(zhí)行此批處理程序中的命令。 任何在命令提示符下可使用的命令都可用在批處理程序中。此外,下面MS-DOS命令是專門在批處理程序中使用的。 = 常用命令 echo、call、pause、rem(小技巧:用:代替rem)是批處理文件最常用的幾個命令,我們就從他們開始學起。 = 注 = 首先, 不是一個命令, 而是DOS 批處理的一個特殊標記符, 僅用于屏蔽命令行回顯. 下面是DOS命令行或批

43、處理中可能會見到的一些特殊標記符: CR(0D) 命令行結(jié)束符 Escape(1B) ANSI轉(zhuǎn)義字符引導符 Space(20) 常用的參數(shù)界定符 Tab(09) ; = 不常用的參數(shù)界定符 + COPY命令文件連接符 * ? 文件通配符 字符串界定符 | 命令管道符 文件重定向符 命令行回顯屏蔽符 / 參數(shù)開關(guān)引導符 : 批處理標簽引導符 % 批處理變量引導符 其次, : 確實可以起到rem 的注釋作用, 而且更簡潔有效; 但有兩點需要注意: 第一, 除了 : 之外, 任何以 :開頭的字符行, 在批處理中都被視作標號, 而直接忽略其后的所有內(nèi)容, 只是為了與正常的標號相區(qū)別, 建議使用 go

44、to 所無法識別的標號, 即在 :后緊跟一個非字母數(shù)字的一個特殊符號. 第二, 與rem 不同的是, :后的字符行在執(zhí)行時不會回顯, 無論是否用echo on打開命令行回顯狀態(tài), 因為命令解釋器不認為他是一個有效的命令行, 就此點來看, rem 在某些場合下將比 : 更為適用; 另外, rem 可以用于 config.sys 文件中. = echo 表示顯示此命令后的字符 echo off 表示在此語句后所有運行的命令都不顯示命令行本身 與echo off相象,但它是加在每個命令行的最前面,表示運行時不顯示這一行的命令行(只能影響當前行)。 call 調(diào)用另一個批處理文件(如果不用call而直

45、接調(diào)用別的批處理文件,那么執(zhí)行完那個批處理文件后將無法返回當前文件并執(zhí)行當前文件的后續(xù)命令)。 pause 運行此句會暫停批處理的執(zhí)行并在屏幕上顯示Press any key to continue.的提示,等待用戶按任意鍵后繼續(xù) rem 表示此命令后的字符為解釋行(注釋),不執(zhí)行,只是給自己今后參考用的(相當于程序中的注釋)。 = 注 = 此處的描述較為混亂, 不如直接引用個命令的命令行幫助更為條理 - ECHO 當程序運行時,顯示或隱藏批處理程序中的正文。也可用于允許或禁止命令的回顯。 在運行批處理程序時,MS-DOS一般在屏幕上顯示(回顯)批處理程序中的命令。 使用ECHO命令可關(guān)閉此功

46、能。 語法 ECHO ON|OFF 若要用echo命令顯示一條命令,可用下述語法: echo message 參數(shù) ON|OFF 指定是否允許命令的回顯。若要顯示當前的ECHO的設置,可使用不帶參數(shù)的ECHO 命令。 message 指定讓MS-DOS在屏幕上顯示的正文。 - CALL 從一個批處理程序中調(diào)用另一個批處理程序,而不會引起第一個批處理的中止。 語法 CALL drive:pathfilename batch-parameters 參數(shù) drive:pathfilename 指定要調(diào)用的批處理程序的名字及其存放處。文件名必須用.BAT作擴展名。 batch-parameters 指

47、定批處理程序所需的命令行信息。 - PAUSE 暫停批處理程序的執(zhí)行并顯示一條消息,提示用戶按任意鍵繼續(xù)執(zhí)行。只能在批處 理程序中使用該命令。 語法 PAUSE REM 在批處理文件或CONFIG.SYS中加入注解。也可用REM命令來屏蔽命令(在CONFIG.SYS 中也可以用分號 ; 代替REM命令,但在批處理文件中則不能替代)。 語法 REM string 參數(shù) string 指定要屏蔽的命令或要包含的注解。 = 例1:用edit編輯a.bat文件,輸入下列內(nèi)容后存盤為c:a.bat,執(zhí)行該批處理文件后可實現(xiàn):將根目錄中所有文件寫入 a.txt中,啟動UCDOS,進入WPS等功能。 批處理

48、文件的內(nèi)容為: 命令注釋: echo off 不顯示后續(xù)命令行及當前命令行 dir c:*.* a.txt 將c盤文件列表寫入a.txt call c:ucdosucdos.bat 調(diào)用ucdos echo 你好 顯示你好 pause 暫停,等待按鍵繼續(xù) rem 準備運行wps 注釋:準備運行wps cd ucdos 進入ucdos目錄 wps 運行wps 批處理文件的參數(shù) 批處理文件還可以像C語言的函數(shù)一樣使用參數(shù)(相當于DOS命令的命令行參數(shù)),這需要用到一個參數(shù)表示符%。 %1-9表示參數(shù),參數(shù)是指在運行批處理文件時在文件名后加的以空格(或者Tab)分隔的字符串。變量可以從%0到%9,%

49、0表示批處理命令本身,其它參數(shù)字符串用%1到%9順序表示。 例2:C:根目錄下有一批處理文件名為f.bat,內(nèi)容為: echo off format %1 如果執(zhí)行C:f a: 那么在執(zhí)行f.bat時,%1就表示a:,這樣format %1就相當于format a:,于是上面的命令運行時實際執(zhí)行的是format a: 例3:C:根目錄下一批處理文件名為t.bat,內(nèi)容為: echo off type %1 type %2 那么運行C:t a.txt b.txt %1 : 表示a.txt %2 : 表示b.txt 于是上面的命令將順序地顯示a.txt和b.txt文件的內(nèi)容。 = 注 = 參數(shù)在批

50、處理中也作為變量處理, 所以同樣使用百分號作為引導符, 其后跟0-9中的一個數(shù)字構(gòu)成參數(shù)引用符. 引用符和參數(shù)之間 (例如上文中的 %1 與 a: ) 的關(guān)系類似于變量指針與變量值的關(guān)系. 當我們要引用第十一個或更多個參數(shù)時, 就必須移動DOS 的參數(shù)起始指針. shift 命令正充當了這個移動指針的角色, 它將參數(shù)的起始指針移動到下一個參數(shù), 類似C 語言中的指針操作. 圖示如下: 初始狀態(tài), cmd 為命令名, 可以用 %0 引用 cmd arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 | | | | | | | | | | %0 %1

51、 %2 %3 %4 %5 %6 %7 %8 %9 經(jīng)過1次shift后, cmd 將無法被引用 cmd arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 | | | | | | | | | | %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 經(jīng)過2次shift后, arg1也被廢棄, %9指向為空, 沒有引用意義 cmd arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 | | | | | | | | | %0 %1 %2 %3 %4 %5 %6 %7 %8 遺憾的是, win9

52、x 和DOS下均不支持 shift 的逆操作. 只有在 nt 內(nèi)核命令行環(huán)境下, shift 才支持 /n 參數(shù), 可以以第一參數(shù)為基準返復移動起始指針. = 特殊命令 if goto choice for是批處理文件中比較高級的命令,如果這幾個你用得很熟練,你就是批處理文件的專家啦。 一、if 是條件語句,用來判斷是否符合規(guī)定的條件,從而決定執(zhí)行不同的命令。 有三種格式: 1、if not 參數(shù) = 字符串 待執(zhí)行的命令 參數(shù)如果等于(not表示不等,下同)指定的字符串,則條件成立,運行命令,否則運行下一句。 例:if %1=a format a: = if 的命令行幫助中關(guān)于此點的描述為:

53、 IF NOT string1=string2 command 在此有以下幾點需要注意: 1. 包含字符串的雙引號不是語法所必須的, 而只是習慣上使用的一種防空字符 2. string1 未必是參數(shù), 它也可以是環(huán)境變量, 循環(huán)變量以及其他字符串常量或變量 3. command 不是語法所必須的, string2 后跟一個空格就可以構(gòu)成一個有效的命令行 = 2、if not exist 路徑文件名 待執(zhí)行的命令 如果有指定的文件,則條件成立,運行命令,否則運行下一句。 如: if exist c:config.sys type c:config.sys 表示如果存在c:config.sys文件

54、,則顯示它的內(nèi)容。 * 注 * 也可以使用以下的用法: if exist command device 是指DOS系統(tǒng)中已加載的設備, 在win98下通常有: AUX, PRN, CON, NUL COM1, COM2, COM3, COM4 LPT1, LPT2, LPT3, LPT4 XMSXXXX0, EMMXXXX0 A: B: C: ., CLOCK$, CONFIG$, DblBuff$, IFS$HLP$ 具體的內(nèi)容會因硬軟件環(huán)境的不同而略有差異, 使用這些設備名稱時, 需要保證以下三點: 1. 該設備確實存在(由軟件虛擬的設備除外) 2. 該設備驅(qū)動程序已加載(aux, prn

55、等標準設備由系統(tǒng)缺省定義) 3. 該設備已準備好(主要是指a: b: ., com1., lpt1.等) 可通過命令 mem/d | find device /i 來檢閱你的系統(tǒng)中所加載的設備 另外, 在DOS系統(tǒng)中, 設備也被認為是一種特殊的文件, 而文件也可以稱作字符設備; 因為設備(device)與文件都是使用句柄(handle)來管理的, 句柄就是名字, 類似于文件名, 只不過句柄不是應用于磁盤管理, 而是應用于內(nèi)存管理而已, 所謂設備加載也即指在內(nèi)存中為其分配可引用的句柄. = 3、if errorlevel 待執(zhí)行的命令 很多DOS程序在運行結(jié)束后會返回一個數(shù)字值用來表示程序運行的

56、結(jié)果(或者狀態(tài)),通過if errorlevel命令可以判斷程序的返回值,根據(jù)不同的返回值來決定執(zhí)行不同的命令(返回值必須按照從大到小的順序排列)。如果返回值等于指定的數(shù)字,則條件成立,運行命令,否則運行下一句。 如if errorlevel 2 goto x2 = 注 = 返回值從大到小的順序排列不是必須的, 而只是執(zhí)行命令為 goto 時的習慣用法, 當使用 set 作為執(zhí)行命令時, 通常會從小到大順序排列, 比如需將返回碼置入環(huán)境變量, 就需使用以下的順序形式: if errorlevel 1 set el=1 if errorlevel 2 set el=2 if errorlevel

57、 3 set el=3 if errorlevel 4 set el=4 if errorlevel 5 set el=5 . 當然, 也可以使用以下循環(huán)來替代, 原理是一致的: for %e in (1 2 3 4 5 6 7 8.) do if errorlevel %e set el=%e 更高效簡潔的用法, 可以參考我寫的另一篇關(guān)于獲取 errorlevel 的文章 出現(xiàn)此種現(xiàn)象的原因是, if errorlevel 比較返回碼的判斷條件并非等于, 而是大于等于. 由于 goto 的跳轉(zhuǎn)特性, 由小到大排序會導致在較小的返回碼處就跳出; 而由于 set命令的 重復 賦值特性, 由大到小

58、排序會導致較小的返回碼 覆蓋 較大的返回碼. 另外, 雖然 if errorlevel= command 也是有效的命令行, 但也只是 解釋命令行時將 = 作為命令行切分符而忽略掉罷了 = 二、goto 批處理文件運行到這里將跳到goto所指定的標號(標號即label,標號用:后跟標準字符串來定義)處,goto語句一般與if配合使用,根據(jù)不同的條件來執(zhí)行不同的命令組。 如: goto end :end echo this is the end 標號用:字符串來定義,標號所在行不被執(zhí)行。 = willsort 編注 label 常被譯為 標簽 , 但是這并不具有廣泛的約定性. goto 與 :

59、聯(lián)用可實現(xiàn)執(zhí)行中途的跳轉(zhuǎn), 再結(jié)合 if 可實現(xiàn)執(zhí)行過程的條件分支, 多個 if 即可實現(xiàn)命令的分組, 類似 C 中 switch case 結(jié)構(gòu)或者 Basic 中的 select case 結(jié)構(gòu), 大規(guī)模且結(jié)構(gòu)化的命令分組即可實現(xiàn)高級語言中的函數(shù)功能. 以下是批處理和C/Basic在語法結(jié)構(gòu)上的對照: Batch C / Basic goto&: goto&: goto&:&if if&else / if&elseif&endif goto&:&if. switch&case / select case goto&:&if&set&envar. function() / function(

60、),sub() = 三、choice 使用此命令可以讓用戶輸入一個字符(用于選擇),從而根據(jù)用戶的選擇返回不同的errorlevel,然后于if errorlevel配合,根據(jù)用戶的選擇運行不同的命令。 注意:choice命令為DOS或者Windows系統(tǒng)提供的外部命令,不同版本的choice命令語法會稍有不同,請用choice /?查看用法。 choice的命令語法(該語法為Windows 2003中choice命令的語法,其它版本的choice的命令語法與此大同小異): CHOICE /C choices /N /CS /T timeout /D choice /M text 描述: 該工

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論