1. 如何理解《Unix 編程藝術》中所說,「提供機制,而不是策略」
前者是 Unix 創建進程的函數,後者是 Windows 的。 但是,機制和策略的界限並不是靜止的。所以,Unix 還有另一個編程藝術:模塊應該是可替換的。比如當年高度考慮策略靈活的 X,在今天的環境下(遠程登陸已經被 VNC 等基於 pixel 的協議代替,顯卡的加速能力提高)已經不適用。所以 X 被策略更少但是效率更高的模塊替代。
2. UNIX編程藝術的介紹
本書寫作了五年之久,作者將UNIX三十年中未見紙端的艱難勝利的軟體工程智慧融入文字,使UNIX家族成為最好最具創新軟體的哲學、設計模式、工具、文化和傳統,Raymond將之第一次帶給我們,並向我們展示它們如何影響著當今的Linux和開源運動。通過大量來自頂尖項目的實例,你將學會如何運用這些智慧經驗來建造更優雅、更可移植、更加好用和更加長久的軟體。
3. UNIX編程藝術的序
Unix is not so much an operating system as an oral history.
與其說Unix是個操作系統,不如說是一部口述歷史。
——Neal Stephenson
知識和專能差異巨大,憑借知識可以推斷出該做什麼,而專能讓你甚至在無意之間,條件反射似的把事情做好。
這本書確實有關「知識」,但更著眼於「專能」。你將學到那些Unix專家們都不自知的Unix開發知識。少一點技術,多一些共享文化:顯見和隱微的,直觀和潛流的——這是本書和大多數Unix書籍不同的地方——不止於方法,更重乎理念。
理念於實用大有裨益,有太多設計不良的軟體:體積臃腫,難於維護、移植和擴展——這些都是蹩腳設計的癥候。我們希望本書的讀者能品出什麼是Unix所教示的良好設計。
本書分為四部分:場景、設計、工具和社群。第一部分(場景)涉及哲學和歷史,為後續內容埋下伏筆。第二部分(設計)將Unix哲學的原理細分為有關設計與實現的、更專門的建議。第三部分(工具)著眼於Unix所提供的工具,可助你解決問題。第四部分(社群)則講述人與人之間的事務與約定,而這正是Unix文化擁有高效能的原因。
這本書是關於共享文化的,我從未想像過獨自完成它。你會發現正劇中包含數位Unix資深專家的客串演出,正是這些人塑造了Unix的習俗。本書曾有過公開大范圍的審閱過程,這期間我邀請這些明星人士對書稿進行評審與研論。這些意見沒有湮沒在本書定稿中,而你可以在書中聆聽到他們的真實聲音:無論是為本書吶喊助陣、還是搖頭反對。
本書中用到人稱「我們」時,我並不是虛張聲勢,僅以此說明這是整個社群都清楚明了的事實。
因為本書著力傳遞文化,因此加入了很多野史和坊間傳說,這在技術書中並不多見。希望你喜歡,這些東西其實是Unix程序員的教養。須彌不重,芥子不輕。我們希望以這種方式更好地講述故事。了解Unix的由來和變遷,會培養你對Unix風格的直覺。
同樣地,基於此,我們不打算使用回述歷史的腔調。你會發現本書參考了眾多時下信息。我們不希望給你一種錯覺:書里說的都是亘古不變的終極真理。參考時下的信息這一做法,也提醒讀者,三十年河東,三十年河西,眼前所見,也許過不了多久就會過時,而需要重新檢省。
另外,本書不是C教程,不是Unix命令和API的手冊,不是sed/yacc/Perl/Python的語言參考,也不是網路編程入門,更不是巨細靡遺的令人費解的X指南。本書也不打算帶你巡遊Unix內幕和體系。有很多其它的好書涵蓋這些領域,本書會在適當的時候告訴你該看哪些。
在這些技術細節外,Unix文化有一個未見諸筆端的行工傳統,以熟練工的考量,它已經有幾百萬人年的發展 。本書即立足於這樣一個信念:領會此傳統,並將它的設計手法應用到手邊,你將成為更好的程序員和設計師。
構成文化的是人,一直以來,獲知文化的方式大約是口口相傳、潛移默化。本書不打算取代人際的文化傳播,但可以促進這一過程,使你能俯耳傾聽他人的心聲。
誰應該看這本書
如果你是個Unix編程老手,經常教導菜鳥,或者與人進行操作系統論戰時無法闡明使用Unix方案所帶來的好處時,可以看看這本書。
如果你是個C、C++或者Java程序員,有其它操作系統的開發經驗,現在輪到你開展一個Unix項目時,可以看看這本書。
如果你是個初級或者中級水平的Unix用戶,但是沒什麼開發經驗,想學習在Unix下如何高效地設計軟體時,可以看看這本書。
如果你不在Unix下編程卻發覺Unix的傳統給你帶來某種啟迪,那你就對了,Unix哲學適用於其它的操作系統。因此我們會花比其它Unix書籍更多的篇幅關注非Unix環境(特別是微軟的操作系統);當所用到工具或者案例可用於其它操作系統時,我們會告訴你。
如果你是一個系統架構師,正為通用市場或垂直應用准備平台方案或實現策略時可以看看這本書。本書將幫助你了解Unix作為開發平台的強大功能,以及開放源碼這個Unix的傳統所帶來的開發方式。
如果你想學到C編程的細節或者想知道怎麼用Unix內核API,本書可能不適合你。Advanced Programming in theUnix Environment [Stevens92]是探究Unix API的經典名著;The Practice of Programming [Kernighan-Pike99]是每個C程序員的必讀書目(任何語言的程序員都該看看這本書)。
如何使用這本書
這本書既重實踐,更富理念;既包含警世格言,又不忘檢點Unix開發中的特殊案例。在每個警句前後,都有生動實例闡明其由來,這些例子絕不來自小兒科式的示常式序,而均出自真實世界滿眼所見的運行代碼。
我們著力避免以大量代碼或者規範文件來胡亂湊數,當然這么做會讓本書的寫作輕松許多(某些地方或許讀起來也更輕松)。絕大多數編程書籍只授你以魚,而本書避免這種做法,力求培養讀者「探求事情何以如此」的感知力。
正由於此,本書會時常請你閱讀代碼與規範文檔,它們中極少量的內容會附在書中,其餘部分我們會在舉例時告訴你如何從網上獲取。
從這些範例中汲取養分,將有助你將所學原則消化變為皰丁之技。如果你能就著一部跑在Unix系統上的網頁瀏覽器來讀書,是再理想不過的了。任何Unix系統都適合,但是我們將要研究的案例大多都會預裝在、或者可以從Linux系統上獲得,書中會提示請你瀏覽或親身感受它們。這些提示通常是按部就班的,跑開玩一會兒並不會打散整個講述過程的連續性。
注意:我們雖力求,但無法給你打保票,聲稱我們所引用的URLs穩定可用。如果你發現某個引用連接已陳舊過時,來點常識,用你喜愛的搜索引擎來個短語搜索。如有可能,我們會在所引用的URLs附近給出如何搜索的提示。
大多數縮寫形式會在首次出現時伴隨其全稱。為方便起見,我們在附錄中提供了名詞對照表。
交叉索引通常以作者名字為主導詞。帶編號的腳注是那些可能會擾亂你閱讀正文,或者是易變的URLs;也可能是旁徵博引的戰爭故事或者笑話 。
為了使這本書不至於讓非技術人員太過難讀,我們邀請了一些非程序員試讀,並指出一些晦澀但起貫穿作用的詞彙。我們把那些編程老手不太會需要的名詞解釋也放在腳注中。
相關引文
一些Unix早期拓荒者的著名論文和書籍,比如Kernighan和Pike的《The Unix Programming Environment》[Kernighan-Pike84]就是其中佼佼者,被世人尊為圭臬。而今看來此書廉頗老矣,它沒提到Internet、萬維網以及諸如Perl、Tcl和Python這些解釋型語言的新秀。
寫作本書的中途我們借鑒了Mike Gancarz的《The Unix Philosophy》[Gancarz]。這本書在它的覆蓋范圍內極其優秀,但是我們覺得需要更多內容才能反映出事情的全貌。盡管如此我們仍對此書作者心存感激,他愈發使我們知道最簡單的Unix設計手法就是最持久耐用的。
《The Pragmatic Programmer》[Hunt-Thomas]是一本關於良好設計的書,文風機智詼諧,它與本書相比,傾向於軟體設計工藝的另一個層面(更注重編碼,而少著墨於高層面的問題劃分)。作者的哲學是其Unix領域耕耘的成果,也是本書內容極好的補充。
《The Practice of Programming》[Kernighan-Pike99]包含了一些與《The Pragmatic Programmer》共通的內容,但更鑽入Unix傳統的深處。
最後(明知道會激怒你),我們推薦《Zen Flesh, Zen Bones》[Reps-Senzaki],一部重要的佛教禪宗本源的合集。對禪的引用書目遍布全書。我們將這些書目包含進來,是因為禪為表達某種想法提供了豐富的語匯,而在軟體設計中卻很難爛熟於心。信奉宗教的讀者,請您不要把禪當成宗教,它是一種心靈雞湯似的東西,純凈而沒有神靈的干擾——此即是禪。
本書的習俗約定
術語「UNIX」技術上和法律上講,是The Open Group的商標,並且應該僅限於那些通過The Open Group嚴格的「符合標准」認證的操作系統。本書中我們使用其較寬松的定義,即大多數程序員所指的,Bell實驗室Unix代碼的後裔或旁支。在這個意義下,Linux(大多數例子都舉自它)也算是一種Unix。
本書也使用了Unix手冊頁(manual page)的傳統,即以括弧括起來的手冊節號來標記Unix設施。通常用於強調一個Unix命令首次出現。比如「munger(1)」可解讀為「munger程序加入存在於你的系統中,其文檔位於Unix手冊頁的第1節」。第2節是C的系統調用,第3節是C的庫函數調用,第5節是文件格式與協議,第8節是系統管理工具。其它節號本書未曾用到,其定義在各個Unix系統各有不同。在你的Unix外殼提示符下輸入man 1 man(老式的System VUnix系統可能要輸入man -s 1 man)以獲得更多信息。
有時我們會提及某個Unix程序(比如Emacs),後面沒有手冊節號而且首字母大寫。這意味這個名字代表一族Unix程序,其基本功能相同,而我們將討論其通用特性。比如Emacs,就包含了xemacs。
本書很多地方我們同時給出了老式(old school)和新式(new school)解法。new-school和rap音樂一樣,開始於1990年前後。在這個含義下,我們往往把它與腳本語言、圖形用戶界面、開放源碼的Unix和萬維網聯系起來。Old-school指代1990年以前(特別是1985年以前)的世界:昂貴的共用計算機、專屬的Unix,shell腳本和無所不在的C。值得指出這些差異,機器越來越便宜,內存多了起來,這些有如暗流,漸漸影響著Unix編程的風格。
所用案例
很多編程書籍為證明某一觀點而特地造出一個範例,你手中這本書不這么干。我們的案例研究均來自真實世界,在生產環境中工作已久。下面是一些主要案例:
cdrtools/xcdroast
這兩個獨立的項目通常被一並使用。cdrtools是一組刻盤工具(用關鍵字「cdrtools」可以在網上找到)。xcdroast是cdrtools的圖型界面前端,其項目網站。
fetchmail
fetchmail用於從遠程郵件伺服器上收信,支持POP3和IMAP郵箱協議。其主頁為,也可以用關鍵字「fetchmail」從網上找到。
GIMP
GIMP(GNU Image Manipulation Program,GNU圖像處理程序)是一個全特性的繪畫和圖像處理程序,可對多種圖像格式進行復雜處理。其源碼可從GIMP主頁獲得(也可以通過關鍵字「GIMP」從網上搜到)。
mutt
mutt郵件客戶端是目前各類基於文本的郵件客戶端程序中的翹楚,提供對MIME(Multipurpose Internet Mail Extensions)、個人隱私輔助程序,如PGP(Pretty Good Privacy)和GPG(GNU Privacy Guard)等特性的絕佳支持。其源碼和二進制可執行文件可以從Mutt項目主頁獲得。
xmlto
xmlto可將DocBook和其它XML文檔以多種格式渲染輸出,包括HTML、純文本和PostScript。其源碼和文檔可在xmlto主頁獲得。
為了將讀者理解本書例子所要閱讀的代碼量降低到最小程度,我們盡量挑選那些可重復使用、並能體現多種不同設計原理和設計實踐的案例。出於同樣原因,很多示例來自於我本人的項目。我沒想說這些例子最為恰當,只是我覺得它們對闡述我的觀點非常有用。
作者致謝
各位客串貢獻者(Ken Arnold, Steven M. Bellovin, Stuart Feldman, Jim Gettys, Steve Johnson, Brian Kernighan, David Korn, Mike Lesk, Doug McIlroy, Marshall Kirk McKusick, Keith Packard, Henry Spencer, 和Ken Thompson)為本書增添極大價值。特別是Doug McIlroy,給予本書恪盡職責、鞭辟入裡的評注的同時,也展現了他早在30年前管理最原始的Unix研究組時鞠躬盡瘁的高風亮節。
我要對Rob Landley和我的妻子Catherine Raymond致以特別感謝,他們都不厭其煩地逐行對本書手稿進行審閱。Rob的深富洞察力的細致評述激勵我在最終稿中加入了一整章內容,他為本書的組織結構與取材范圍奉獻極多。如果把他所給予的改進意見落在筆端,那他無愧於本書的合著者。Cathy代表讀者中非技術人員的一群,如果那些非程序員讀者覺得本書並不難讀,那全是她的功勞。
寫作的五年間,本書從不少人的討論意見中獲益良多。Mark M. Miller使我對線程有了更深的認識。John Cowan教給我不少介面設計方式,並起草了wily和VM/CMS的學習案例。Jef Raskin告訴我Rule of Least Surprise的由來。UIUC System Architecture Group對前幾章給出的反饋彌足珍貴,What Unix Gets Wrong和Flexibility in Depth兩節是他們直接激勵的結果。Russell J. Nelson提供了Bernstein chaining的素材。第3章中MVS學習案例大部分的材料來自Jay Maynard。Les Hatton對語言一章給出很多有益建議,並促使我寫成第4章中Optimal Mole Size的部分內容。David A. Wheeler貢獻了很多發人深省的批評,以及一些學習案例(特別是在設計部分中)的素材。Russ Cox幫助我進行了Plan 9的調查。Dennis Ritchie糾正了我的一些錯誤的C歷史觀念。
成百上千的Unix程序員,人數太多以至於無法在此列出他們的名字,在2003年1月到6月間的公開審閱過程間給了我建議和評論。開放的同級復審這一過程讓我覺得緊張刺激而回報極多。當然,任何最終書稿中殘留的錯誤都是我自己的責任。
「把事情說透」的風格,以及其它一些考慮因素,是受到了「設計模式運動」的影響;說實話,我對到處堆砌Unix設計模式這種做法深不以為然。我對此運動的中心教條不敢苟同,並且沒覺得把設計模式嚴格付諸實用有什麼必要,也不想背上這種思想的包袱。盡管如此,我的行事方法仍然受到Christopher Alexander成果 (特別是《Timeless Way of Building》和《A Pattern Language》兩文)的影響。Gang of Four和他們的信徒為我展示了如何用Alexander的思想,站在較高層面上,拋去含混不清的對設計通則的空話,來談論軟體設計,這一點我心存感激,永誌不忘。對設計模式有興趣的讀者可以看看這本書《Design Patterns: Elements of Reusable Object-Oriented Software [GangOfFour]》。
本書標題毫無疑問是借鑒了Donald Knuth的《The Art of Computer Programming》一書的書名。Knuth和Unix傳統文化沒什麼聯系,但他影響了我們每一個人。
有先見之明和豐富想像力的編輯並不多,好在Mark Taub就是一個,他從並不看好的項目中發現了閃光點,並極富技巧地促成了這本書的寫作。文字編輯中,文筆好而又能幫助別人提高文筆的就更少了,所幸Mary Lou Nohr是其中之一。Jerry Votta的封面設計領會了我的意圖,而且做得比我的想像還要漂亮。Addison-Wesley的編輯們讓審稿和出版這一過程不再枯燥無味,我天生怕被人管,但是他們仍然極力配合我,使得文字、版面、圖片和市場工作都達到極高水準。
4. 麻煩給完整編程
print('\n'.join(input('請輸入多種水果名稱:').strip().split()))
5. UNIX編程藝術的目 錄
序 xxv
Part I 1
第1章 哲學 3
1.1 文化?什麼文化 3
1.2 Unix的生命力 4
1.3 反對學習Unix文化的理由 5
1.4 Unix之失 6
1.5 Unix之得 7
1.5.1 開源軟體 7
1.5.2 跨平台可移植性和開放標准 8
1.5.3 Internet和萬維網 8
1.5.4 開源社區 9
1.5.5 從頭到腳的靈活性 9
1.5.6 Unix Hack之趣 10
1.5.7 Unix的經驗別處也可適用 11
1.6 Unix哲學基礎 11
1.6.1 模塊原則:使用簡潔的介面拼合簡單的部件 14
1.6.2 清晰原則: 清晰勝於機巧 14
1.6.3 組合原則:設計時考慮拼接組合 15
1.6.4 分離原則: 策略同機制分離,介面同引擎分離 16
1.6.5 簡潔原則:設計要簡潔,復雜度能低則低 17
1.6.6 吝嗇原則: 除非確無它法,不要編寫龐大的程序 18
1.6.7 透明性原則:設計要可見,以便審查和調試 18
1.6.8 健壯原則: 健壯源於透明與簡潔 18
1.6.9 表示原則: 把知識疊入數據以求邏輯質朴而健壯 19
1.6.10 通俗原則:介面設計避免標新立異 20
1.6.11 緘默原則:如果一個程序沒什麼好說的,就保持沉默 20
1.6.12 補救原則: 出現異常時,馬上退出並給出足量錯誤信息 21
1.6.13 經濟原則: 寧花機器一分,不花程序員一秒 22
1.6.14 生成原則: 避免手工hack,盡量編寫程序去生成程序 22
1.6.15 優化原則: 雕琢前先得有原型,跑之前先學會走 23
1.6.16 多樣原則:決不相信所謂「不二法門」的斷言 24
1.6.17 擴展原則: 設計著眼未來,未來總比預想快 24
1.7 Unix哲學之一言以蔽之 25
1.8 應用Unix哲學 26
1.9 態度也要緊 26
第2章 歷史——雙流記 29
2.1 Unix的起源及歷史,1969-1995 29
2.1.1 創世紀:1969-1971 30
2.1.2 出埃及記:1971-1980 32
2.1.3 TCP/IP 和Unix內戰:1980-1990 35
2.1.4 反擊帝國:1991-1995 41
2.2 黑客的起源和歷史:1961-1995 43
2.2.1 游戲在校園的林間:1961-1980 44
2.2.2 互聯網大融合與自由軟體運動:1981-1991 45
2.2.3 Linux 和實用主義者的應對:1991-1998 48
2.3 開源運動:1998年及之後 49
2.4 Unix的歷史教訓 51
第3章 對比: Unix哲學同其他哲學的比較 53
3.1 操作系統的風格元素 53
3.1.1 什麼是操作系統的統一性理念 54
3.1.2 多任務能力 54
3.1.3 協作進程 55
3.1.4 內部邊界 57
3.1.5 文件屬性和記錄結構 57
3.1.6 二進制文件格式 58
3.1.7 首選用戶界面風格 58
3.1.8 目標受眾 59
3.1.9 開發的門坎 60
3.2 操作系統的比較 61
3.2.1 VMS 61
3.2.2 MacOS 64
3.2.3 OS/2 65
3.2.4 Windows NT 68
3.2.5 BeOS 71
3.2.6 MVS 72
3.2.7 VM/CMS 74
3.2.8 Linux 76
3.3 種什麼籽,得什麼果 78
Part II 81
第4章 模塊性:保持清晰,保持簡潔 83
4.1 封裝和最佳模塊大小 85
4.2 緊湊性和正交性 87
4.2.1 緊湊性 87
4.2.2 正交性 89
4.2.3 SPOT原則 91
4.2.4 緊湊性和強單一中心 92
4.2.5 分離的價值 94
4.3 軟體是多層的 95
4.3.1 自頂向下和自底向上 95
4.3.2 膠合層 97
4.3.3 實例分析:被視為薄膠合層的C語言 98
4.4 程序庫 99
4.4.1 實例分析:GIMP插件 100
4.5 Unix和面向對象語言 101
4.6 模塊式編碼 103
第5章 文本化:好協議產生好實踐 105
5.1 文本化的重要性 107
5.1.1 實例分析:Unix口令文件格式 109
5.1.2 實例分析:.newsrc格式 110
5.1.3 實例分析:PNG圖形文件格式 111
5.2 數據文件元格式 112
5.2.1 DSV 風格 113
5.2.2 RFC 822 格式 114
5.2.3 Cookie-Jar格式 115
5.2.4 Record-Jar格式 116
5.2.5 XML 117
5.2.6 Windows INI 格式 119
5.2.7 Unix文本文件格式的約定 120
5.2.8 文件壓縮的利弊 122
5.3 應用協議設計 123
5.3.1 實例分析:SMTP,一個簡單的套接字協議 124
5.3.2 實例分析:POP3,郵局協議 124
5.3.3 實例分析:IMAP,互聯網消息訪問協議 126
5.4 應用協議元格式 127
5.4.1 經典的互聯網應用元協議 127
5.4.2 作為通用應用協議的HTTP 128
5.4.3 BEEP:塊可擴展交換協議 130
5.4.4 XML-RPC,SOAP和Jabber 131
第6章 透明性:來點兒光 133
6.1 研究實例 135
6.1.1 實例分析:audacity 135
6.1.2 實例分析:fetchmail的–v選項 136
6.1.3 實例分析:GCC 139
6.1.4 實例分析:kmail 140
6.1.5 實例分析:SNG 142
6.1.6 實例分析:Terminfo資料庫 144
6.1.7 實例分析:Freeciv數據文件 146
6.2 為透明性和可顯性而設計 148
6.2.1 透明性之禪 149
6.2.2 為透明性和可顯性而編碼 150
6.2.3 透明性和避免過度保護 151
6.2.4 透明性和可編輯的表現形式 152
6.2.5 透明性、故障診斷和故障恢復 153
6.3 為可維護性而設計 154
第7章 多道程序設計: 分離進程為獨立的功能 157
7.1 從性能調整中分離復雜度控制 159
7.2 Unix IPC 方法的分類 160
7.2.1 把任務轉給專門程序 160
7.2.2 管道、重定向和過濾器 161
7.2.3 包裝器 166
7.2.4 安全性包裝器和Bernstein鏈 167
7.2.5 從進程 168
7.2.6 對等進程間通信 169
7.3 要避免的問題和方法 176
7.3.1 廢棄的Unix IPC方法 176
7.3.2 遠程過程調用 178
7.3.3 線程——恐嚇或威脅 180
7.4 在設計層次上的進程劃分 181
第8章 微型語言:尋找歌唱的樂符 183
8.1 理解語言分類法 185
8.2 應用微型語言 187
8.2.1 案例分析:sng 187
8.2.2 案例分析:正則表達式 188
8.2.3 案例分析:Glade 191
8.2.4 案例分析:m4 193
8.2.5 案例分析:XSLT 194
8.2.6 案例分析:The Documenter's Workbench Tools 195
8.2.7 案例分析:fetchmail的運行控制語法 199
8.2.8 案例分析:awk 200
8.2.9 案例分析:PostScript 202
8.2.10 案例分析:bc和dc 203
8.2.11 案例分析:Emacs Lisp 205
8.2.12 案例分析:JavaScript 205
8.3 設計微型語言 206
8.3.1 選擇正確的復雜度 207
8.3.2 擴展和嵌入語言 209
8.3.3 編寫自定義語法 210
8.3.4 宏—慎用 210
8.3.5 語言還是應用協議 212
第9章 生成:提升規格說明的層次 215
9.1 數據驅動編程 216
9.1.1 實例分析:ascii 217
9.1.2 實例分析:統計學的垃圾郵件統計 218
9.1.3 實例分析:fetchmailconf中的元類改動 219
9.2 專用代碼的生成 225
9.2.1 實例分析:生成ascii顯示的代碼 225
9.2.2 實例分析:為列表生成HTML代碼 227
第10章 配置:邁出正確的第一步 231
10.1 什麼應是可配置的 231
10.2 配置在哪裡 233
10.3 運行控制文件 234
10.3.1 實例分析:.netrc文件 236
10.3.2 到其它操作系統的可移植性 238
10.4 環境變數 238
10.4.1 系統環境變數 238
10.4.2 用戶環境變數 240
10.4.3 何時使用環境變數 240
10.4.4 到其它操作系統的可移植性 242
10.5 命令行選項 242
10.5.1 從–a到–z的命令行選項 243
10.5.2 到其它操作系統的可移植性 248
10.6 如何挑選方法 248
10.6.1 實例分析:fetchmail 249
10.6.2 實例分析:XFree86伺服器 251
10.7 論打破規則 252
第11章 介面:Unix環境下的用戶介面設計模式 253
11.1 最小立異原則的應用 254
11.2 Unix介面設計的歷史 256
11.3 介面設計評估 257
11.4 CLI和可視介面之間的權衡 259
11.4.1 實例分析:編寫計算器程序的兩種方式 262
11.5 透明度、表現力和可配置性 264
11.6 Unix介面設計模式 266
11.6.1 過濾器模式 266
11.6.2 Cantrip模式 268
11.6.3 源模式 268
11.6.4 接收器模式 269
11.6.5 編譯器模式 269
11.6.6 ed模式 270
11.6.7 Roguelike 模式 270
11.6.8 「引擎和介面分離」模式 273
11.6.9 CLI伺服器模式 278
11.6.10 基於語言的介面模式 279
11.7 應用Unix介面設計模式 280
11.7.1
11.8 網頁瀏覽器作為通用前端 281
11.9 沉默是金 284
第12章 優化 287
12.1 什麼也別做,就站在那兒 287
12.2 先估量,後優化 288
12.3 非定域性之害 290
12.4 吞吐量和延遲 291
12.4.1 批操作 292
12.4.2 重疊操作 293
12.4.3 緩存操作結果 293
第13章 復雜度:盡可能簡單,但別簡過了頭 295
13.1 談談復雜度 296
13.1.1 復雜度的三個來源 296
13.1.2 介面復雜度和實現復雜度的折中 298
13.1.3 必然的、可能的和偶然的復雜度 299
13.1.4 映射復雜度 300
13.1.5 當簡潔性不能勝任 302
13.2 五個編輯器的故事 302
13.2.1 ed 304
13.2.2 vi 305
13.2.3 Sam 306
13.2.4 Emacs 307
13.2.5 Wily 308
13.3 編輯器的適當規模 309
13.3.1 甄別復雜度問題 309
13.3.2 折衷無用 312
13.3.3 Emacs是個反Unix傳統的論據嗎 314
13.4 軟體的適度規模 316
Part III 319
第14章 語言:C還是非C 321
14.1 Unix下語言的豐饒 321
14.2 為什麼不是C 323
14.3 解釋型語言和混合策略 325
14.4 語言評估 325
14.4.1 C 326
14.4.2 C++ 327
14.4.3 Shell 330
14.4.4 Perl 332
14.4.5 Tcl 334
14.4.6 Python 336
14.4.7 Java 339
14.4.8 Emacs Lisp 342
14.5 未來趨勢 344
14.6 選擇X工具包 346
第15章 工具:開發的戰術 349
15.1 開發者友好的操作系統 349
15.2 編輯器選擇 350
15.2.1 了解vi 351
15.2.2 了解Emacs 351
15.2.3 非虔誠的選擇:兩者兼用 352
15.3 專用代碼生成器 352
15.3.1 yacc和lex 353
15.3.2 實例分析:fetchmailrc的語法 356
15.3.3 實例分析:Glade 356
15.4 make:自動化編譯 357
15.4.1 make的基本理論 357
15.4.2 非C/C++開發中的make 359
15.4.3 通用生成目標 359
15.4.4 生成Makefile 362
15.5 版本控制系統 364
15.5.1 為什麼需要版本控制 364
15.5.2 手工版本控制 365
15.5.3 自動化的版本控制 366
15.5.4 Unix的版本控制工具 367
15.6 運行期調試 369
15.7 性能分析 370
15.8 使用Emacs整合工具 370
15.8.1 Emacs和make 371
15.8.2 Emacs和運行期調試 371
15.8.3 Emacs和版本控制 371
15.8.4 Emacs和Profiling 372
15.8.5 像IDE一樣,但更強 373
第16章 重用:論不要重新發明輪子 375
16.1 豬小兵的故事 376
16.2 透明性是重用的關鍵 379
16.3 從重用到開源 380
16.4 生命中最美好的就是「開放」 381
16.5 何處找 384
16.6 使用開源軟體的問題 385
16.7 許可證問題 386
16.7.1 開放源碼的資格 386
16.7.2 標准開放源碼許可證 388
16.7.3 何時需要律師 390
Part IV 391
第17章 可移植性:軟體可移植性與遵循標准 393
17.1 C語言的演化 394
17.1.1 早期的C語言 395
17.1.2 C 語言標准 396
17.2 Unix 標准 398
17.2.1 標准和Unix之戰 398
17.2.2 慶功宴上的幽靈 401
17.2.3 開源世界的Unix標准 402
17.3 IETF和RFC標准化過程 403
17.4 規格DNA,代碼RNA 405
17.5 可移植性編程 408
17.5.1 可移植性和編程語言選擇 409
17.5.2 避免系統依賴性 412
17.5.3 移植工具 413
17.6 國際化 413
17.7 可移植性、開放標准以及開放源碼 414
第18章 文檔:向網路世界闡釋代碼 417
18.1 文檔概念 418
18.2 Unix風格 420
18.2.1 大文檔偏愛 420
18.2.2 文化風格 421
18.3 各種Unix文檔格式 422
18.3.1 troff和Documenter's Workbench Tools 422
18.3.2 TEX 424
18.3.3 Texinfo 425
18.3.4 POD 425
18.3.5 HTML 426
18.3.6 DocBook 426
18.4 當前的混亂和可能的出路 426
18.5 DocBook 427
18.5.1 文檔類型定義 427
18.5.2 其它DTD 428
18.5.3 DocBook 工具鏈 429
18.5.4 移植工具 431
18.5.5 編輯工具 432
18.5.6 相關標准和實踐 433
18.5.7 SGML 433
18.5.8 XML-DocBook 參考書籍 433
18.6 編寫Unix文檔的最佳實踐 434
第19章 開放源碼:在Unix新社區中編程 437
19.1 Unix和開放源碼 438
19.2 與開源開發者協同工作的最佳實踐 440
19.2.1 良好的修補實踐 440
19.2.2 良好的項目、檔案文件命名實踐 444
19.2.3 良好的開發實踐 447
19.2.4 良好的發行製作實踐 450
19.2.5 良好的交流實踐 454
19.3 許可證的邏輯:如何挑選 456
19.4 為什麼應使用某個標准許可證 457
19.5 各種開源許可證 457
19.5.1 MIT或者X Consortium許可證 457
19.5.2 經典BSD許可證 457
19.5.3 Artistic許可證 458
19.5.4 通用公共許可證 458
19.5.5 Mozilla 公共許可證 459
第20章 未來:危機與機遇 461
20.1 Unix傳統中的必然和偶然 461
20.2 Plan 9:未來之路 464
20.3 Unix設計中的問題 466
20.3.1 Unix文件就是一大袋位元組 466
20.3.2 Unix對GUI的支持孱弱 467
20.3.3 文件刪除不可撤銷 468
20.3.4 Unix假定文件系統是靜態的 469
20.3.5 作業控制設計拙劣 469
20.3.6 Unix API 沒有使用異常 470
20.3.7 ioctl(2)和fcntl(2)是個尷尬 471
20.3.8 Unix安全模型可能太過原始 471
20.3.9 Unix名字種類太多 472
20.3.10 文件系統可能有害論 472
20.3.11 朝向全局互聯網地址空間 472
20.4 Unix的環境問題 473
20.5 Unix文化中的問題 475
20.6 信任的理由 477
附錄A 縮寫詞表 479
附錄B 參考文獻 483
附錄C 貢獻者 495
附錄D 無根的根:無名師的Unix心傳 499
Colophon 510
索引 511