複製鏈接
請複製以下鏈接發送給好友

UNIX編程藝術

(2011年電子工業出版社出版的圖書)

鎖定
《UNIX編程藝術》是2011年1月電子工業出版社出版發行的圖書,作者是Eric S. Raymond。 [1] 
中文名
UNIX編程藝術
作    者
Eric S. Raymond(埃瑞克.S.理曼德)
譯    者
姜宏
何源
蔡曉駿
出版時間
2011年1月
出版社
電子工業出版社
ISBN
9787121123290
類    別
軟件工程
定    價
69 元

UNIX編程藝術內容簡介

本書主要介紹了Unix系統領域中的設計和開發哲學、思想文化體系、原則與經驗,由公認的Unix編程大師、開源運動領袖人物之一Eric S. Raymond傾力多年寫作而成。包括Unix設計者在內的多位領域專家也為本書貢獻了寶貴的內容。本書內容涉及社羣文化、軟件開發設計與實現,覆蓋面廣、內容深邃,完全展現了作者極其深厚的經驗積累和領域智慧。

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.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

UNIX編程藝術作者簡介

Eric S.Raymond 從1982年開始就是UNIX開發者。作為開源社區文化的倡導和呼籲者,他在《大教堂與市集》中寫下了這場運動的宣言,同時他還是《新黑客詞典》的編輯。

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 Module 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的編輯們讓審稿和出版這一過程不再枯燥無味,我天生怕被人管,但是他們仍然極力配合我,使得文字、版面、圖片和市場工作都達到極高水準。
參考資料