UNIX编程艺术
  • 推荐0
  • 收藏1
  • 浏览485

UNIX编程艺术

Eric S. Raymond(埃瑞克.S.理曼德) (作者)  姜宏 (译者)

  • 丛  书:传世经典书丛
  • 书  号:978-7-121-17665-4
  • 出版日期:2012-08-17
  • 页  数:564
  • 开  本:16(185*230)
  • 出版状态:上市销售
  • 原书名: The Art of UNIX Programming
  • 原书号:0131429019
  • 维护人:张春雨
本书主要介绍了Unix系统领域中的设计和开发哲学、思想文化体系、原则与经验,由公认的Unix编程大师、开源运动领袖人物之一Eric S. Raymond倾力多年写作而成。包括Unix设计者在内的多位领域专家也为本书贡献了宝贵的内容。本书内容涉及社群文化、软件开发设计与实现,覆盖面广、内容深邃,完全展现了作者极其深厚的经验积累和领域智慧。
出版说明
悦读上品 得乎益友


孔子云:“取乎其上,得乎其中;取乎其中,得乎其下;取乎其下,则无所得矣”。

对于读书求知而言,这句古训教我们去读好书,最好是好书中的上品——经典书。其中,科技人员要读的技术书,因为直接关乎客观是非与生产效率,阅读选材本更应慎重。然而,随着技术图书品种的日益丰富,发现经典书越来越难,尤其对于涉世尚浅的新读者,更为不易,而他们又往往是最需要阅读、提升的重要群体。

所谓经典书,或说上品,是指选材精良、内容精练、讲述生动、外延丰盈、表现手法体贴入微的读品,它们会成为读者的知识和经验库中的重要组成部分,并且拥有从不断重读中汲取养分的空间。因此,选择阅读上品的问题便成了有效阅读的首要问题。当然,这不只是效率问题,上品促成的既是对某一种技术、思想的真正理解和掌握,同时又是一种感悟或享受,是一种愉悦。

与技术本身类似,经典IT技术书多来自国外。深厚的积累、良好的写作氛围,使一批大师为全球技术学习者留下了璀璨的智慧瑰宝。就在那个年代即将远去之时,无须回眸,也能感受到这一部部厚重而深邃的经典著作,在造福无数读者后从未蒙尘的熠熠光辉。而这些凝结众多当今国内技术中坚美妙记忆与绝佳体验的技术图书,虽然尚在国外图书市场上大放异彩,却已逐渐淡出国人的视线。最为遗憾的是,迟迟未有可以填补空缺的新书问世。而无可替代,不正是经典书被奉为圭臬的原因?

为了不让国内读者,尤其是即将步入技术生涯的新一代读者,就此错失这些滋养过先行者们的好书,以出版IT精品图书,满足技术人群需求为己任的我们,愿意承担这一使命。本次机遇惠顾了我们,让我们有机会携手权威的Pearson公司,精心推出“传世经典书丛”。

在我们眼中,“传世经典”的价值首先在于——既适合喜爱科技图书的读者,也符合专家们挑剔的标准。幸运的是,我们的确找到了这些堪称上品的佳作。丛书带给我们的幸运颇多,细数一下吧。

得以引荐大师著作
有恐思虑不周,我们大量参考了国外权威机构和网站的评选结果,并得到了Pearson的专业支持,又进一步对符合标准之图书的国内外口碑与销售情况进行细致分析,也听取了国内技术专家的宝贵建议,才有幸选出对国内读者最富有技术养分的大师上品。
向深邃的技术内涵致敬
中外技术环境存在差异,很多享誉国外的好书未必适用于国内读者;且技术与应用瞬息万变,很容易让人心生迷惘或疲于奔命。本丛书的图书遴选,注重打好思考方法与技术理念的根基,旨在帮助读者修炼内功,提升境界,将技术真正融入个人知识体系,从而可以一通百通,从容面对随时涌现的技术变化。
翻译与评注的双项选择
引进优秀外版著作,将其翻译为中文供国内读者阅读,较为有效与常见。但另有一些外语水平较高、喜好阅读原版的读者,苦于对技术理解不足,不能充分体会原文表述的精妙,需要有人指导与点拨。而一批本土技术精英经过长期经典熏陶及实践锤炼,已足以胜任这一工作。有鉴于此,本丛书在翻译版的同时推出融合英文原著与中文点评、注释的评注版,供不同志趣的读者自由选择。
承蒙国内一流译(注)者的扶持
优秀的英文原著最终转化为真正的上品,尚需跨越翻译鸿沟,外版图书的翻译质量一直屡遭国内读者诟病。评注版的增值与含金量,同样依赖于评注者的高卓才具。好在,本丛书得到了久经考验的权威译(注)者的认可和支持,首肯我们选用其佳作,或亲自参与评注工作。正是他们的参与保证了经典的品质,既再次为我们的选材把关,更提供了一流的中文表述。

期望带给读者良好的阅读体验
一本好书带给人的愉悦不止于知识收获,良好的阅读感受同样不可缺少,且对学业不无助益。为让读者收获与上品相称的体验,我们在图书装帧设计与选材用料上同样不敢轻率,惟愿送到读者手中的除了珠玑章句,还有舒适与熨帖的视觉感受。

所有参与丛书出版的人员,尽管能力有限,却无不心怀严谨之心与完美愿望。如果读者朋友能从潜心阅读这些上品中偶有获益,不啻为对我们工作的最佳褒奖。若有阅读感悟,敬请拨冗告知,以鼓励我们继续在这一道路上贡献绵薄之力。如有不周之处,也请不吝指教。


电子工业出版社博文视点
二〇一〇年十二月

译序

大多数译序是给作者说好话,顺便带动一下译本销量的,本篇是一个例外。
《The Art of UNIX Programming》,简称TAOUP,作者Eric S. Raymond,简称ESR。这大概是计算机类书籍中很少见的一本课外读物。TCP/IP编程之类典型Unix编程书中讲到的东西在这本书里面找不到,所以书里讲到的当然就是别的书里找不到的东西。读者也许需要有相当的Unix背景、或者长期钻研某个专题,才能体会到作者的弦外之音。ESR作为老牌黑客信手拈来的典故,如果不是在Unix里面长期浸淫,大概很难有所共鸣,所以把这当作Unix的一部坊间史话倒也合适。
本书总结了历史上Unix众多成功的经验和失败的教训、经时间考验和临时搭救的编码策略、大众喜爱和小众受用的实用工具;一些被跨国界信仰地广泛接受,一些则在不同环境中各有见地。被TAOUP总结为失败的,也许恰恰是某些工程的保命神药;总结为成功的,也许正好是压垮另一些工程的最后一根稻草。情景各异而已。书是写给程序员看的,因此很多观点都太过技术味儿,比如所见即所得的编辑器不如手写标记的纯文本更直接——90%的人会想:这怎么可能?!
这本书是给读者增长见识的,很多案例分析不管结论如何,读者都可以从中见到红蓝两方的思维方式和行事方法,以及各方高手看待问题的角度。无论成功还是失败,都只是一念之间,而读者只需要体味出这些对自己过去的、手头的、未来的项目可以有何种借鉴,便已得其中三昧。
网络上关于TAOUP的书评甚多,正负反响各有不少,负面评价大体集中在认为作者视角较窄、对商业公司有偏见以及过分抬爱自己的fetchmail几方面。我个人的感觉,Unix、尤其是开源Unix上有太多好用的工具极欠雕琢,目标受众太过技术。ESR并未回避这些,读者不妨多留意为数不多的痛切之笔。
本书翻译经历一年多的时间,之前我曾经约略翻过纸版,偶尔见到一些合我胃口的言论,于是心有灵犀认为这书不错;然而等到译到中途,便发现ESR实在是个美国愤青,这便是课外读物和工本教程给读者的不同感受了。翻译的过程对译者是精读的过程,但希望读者能用它打发堵车、候机、等人时的无聊时间,这书适合从任何一篇翻起。
翻译过程颇为艰辛:何蔡两位初译,由我统稿。书中寻章摘句之处,我们尽力将其还原。书名保持原文并给出译名,人名不译,专有名词给出原文,特意不加入任何译注。相关背景常识、翻译感受以及付梓后的任何问题,可以在中译版网页上与我们交流。这一年间,侯捷老师的推荐,周筠老师、方舟和兴璐两位编辑、何蔡二位给我的莫大帮助和宽容使得本书最终面世;身边诸位好友同事也不同程度地在各个技术方面给予指导和支持,尤其感谢bz、主任、delphij、kola几位。我的爱人王冰陪我加班,容忍我对程序的沉迷,给我心灵的温暖,是我翻译这本书的力量源泉。
KISS。

姜 宏
2005年12月于北京



Preface
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的图型界面前端,其项目网站为<http://www.xcdroast.org/>。
fetchmail
fetchmail用于从远程邮件服务器上收信,支持POP3和IMAP邮箱协议。其主页为<http://www.catb.org/~esr/fetchmail>,也可以用关键字“fetchmail”从网上找到。
GIMP
GIMP(GNU Image Manipulation Program,GNU图像处理程序)是一个全特性的绘画和图像处理程序,可对多种图像格式进行复杂处理。其源码可从GIMP主页<http://www.gimp.org/>获得(也可以通过关键字“GIMP”从网上搜到)。
mutt
mutt邮件客户端是目前各类基于文本的邮件客户端程序中的翘楚,提供对MIME(Multipurpose Internet Mail Extensions)、个人隐私辅助程序,如PGP(Pretty Good Privacy)和GPG(GNU Privacy Guard)等特性的绝佳支持。其源码和二进制可执行文件可以从Mutt项目主页<http://www.mutt.org>获得。
xmlto
xmlto可将DocBook和其它XML文档以多种格式渲染输出,包括HTML、纯文本

和PostScript。其源码和文档可在xmlto主页<http://cyberelk.net/tim/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的编辑们让审稿和出版这一过程不再枯燥无味,我天生怕被人管,但是他们仍然极力配合我,使得文字、版面、图片和市场工作都达到极高水准。

目录

Contents
序 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

读者评论

同系列书

  • 深度探索C++对象模型

    Stanley B. Lippman (斯坦利·B.·李普曼) (作者) 侯捷 薛艳 (译者)

    Inside The C++ Object Model专注于C++对象导向程序设计的底层机制,包括结构式语意、暂时性对象的生成、封装、继承,以及虚拟——虚拟函数...

    ¥99.00
  • UML精粹:标准对象建模语言简明指南(第3版)

    Martin Fowler(马丁•福勒) (作者) 潘加宇 (译者)

    本书为Martin Fowler所著《UML精粹》一书第3版之中译本。原书首版自1997年间世以来,深受读者欢迎,堪称书中上乘。数年来,内容与时俱进,不断更新,...

    ¥59.00
  • Exceptional C++:47个C++工程难题、编程问题和解决方案(中文版)

    Herb Sutter(赫伯•萨特) (作者) 聂雪军 (译者)

    本书通过示例的方式来讲述如何用标准c++进行正确的软件开发。全书共分8章,包括范型程序设计与c++标准库、异常安全性的问题与技术、类的设计与继承、编译器防火墙和...

    ¥59.00
  • Java编程思想(第4版)(评注版)

    Bruce Eckel(布鲁斯•埃克尔) (作者) 刘中兵 (译者)

    本书的作者拥有多年教学经验,对C、C++以及Java语言都有独到、深入的见解,以通俗易懂及小而直接的示例解释了一个个晦涩抽象的概念。本书共22章,包括操作符、控...

    ¥108.00
  • UNIX编程艺术

    Eric S. Raymond(埃瑞克.S.理曼德) (作者) 姜宏 (译者)

    本书主要介绍了Unix系统领域中的设计和开发哲学、思想文化体系、原则与经验,由公认的Unix编程大师、开源运动领袖人物之一Eric S. Raymond倾力多年...

    ¥79.00