1700437820
管道是典型的Unix发明,是临时连接程序的一种优雅而高效的方式。让数据流过一系列处理步骤,又自然又直观;语法异常简单;管道机制与小工具集合完美契合。当然,管道并不能解决所有的连接问题,但道格·麦基尔罗伊最初概念中完全通用的非线性连接在实践中并不经常出现,线性管道几乎总是足敷使用。
1700437821
1700437822
将程序当作工具并组合使用是Unix的特色。编写各自做好一件事的小程序,而不是功能繁多的单个大程序,有很多好处。当然,有些时候单体程序有其意义,但能让普通用户以新奇方式组合使用的小程序集合优势明显。
1700437823
1700437824
实际上,这种方法是整个程序层面的模块化,平行于程序内功能层面的模块化。无论哪种模块化,思路都是分而治之,因为各个组件都更小,而且不相互影响。它还允许混搭使用,大程序中很难实现这种能力,因为大程序试图在单个包中做太多不同的事情。
1700437825
1700437826
普通文本是标准数据格式。文本的普遍使用是一种极大的简化。程序读取字节,如果它们的目的是处理文本,那么这些字节将采用标准表示方式,通常是长短不一的行,每行均以换行符结束。这种做法并非万能,但几近普适,且不必付出太多空间或时间代价。因此,所有这些小工具单独使用或组合起来,就能处理任何数据。
1700437827
1700437828
不妨猜猜看:如果Unix是在使用穿孔卡而不是电传打字机的世界里开发出来的,会有什么不同结果呢?穿孔卡实际上强迫人们形成一种世界观,一切都以80个字符为单位,而信息通常都位于这些字符块的固定字段中。
1700437829
1700437830
能写程序的程序是威力强大的理念。我们在计算领域取得的大部分进步都在于实现机械化——让计算机为我们做更多的工作。手工编写程序很困难,所以如果能让程序来为你编写程序,可谓大胜。这样做更省力,而且生成的程序更有可能是正确的。
1700437831
1700437832
编译器当然算是比较老的例子,但在更高的层面上,Yacc和Lex是生成代码、创建编程语言的典范。shell脚本和makefile等自动化和机械化工具实际上也是创建程序的程序。这些工具今天仍然被广泛使用,有时以尺寸庞大的配置脚本和makefile生成器的形式,与Python等语言的源代码发行版和GCC等编译器一起出现。
1700437833
1700437834
专用语言,今天常被称为小语言(little language)、领域特定语言(domain-specific language)或应用特定语言(application-specific language)。我们通过语言告诉计算机应该做什么。对于大多数程序员来说,这意味着使用像C这样的通用语言,但另外还有许多更专业的语言,它们专注于更狭窄的领域。
1700437835
1700437836
shell就是好例子:它是用来运行程序的,而且它在这方面非常擅长,但你不会想用它来写浏览器或视频游戏。当然,专业化是古老的概念,最早的高级语言都是针对特定目标的,如Fortran针对科学和工程计算,COBOL针对商业数据处理。妄图“上下通吃”的“语言先烈”也不罕见,PL/I就是其中之一。
1700437837
1700437838
Unix对特殊用途语言的支持由来已久,并非仅有shell。我所熟悉的文档编制工具就是很好的例子,计算器、电路设计语言、脚本语言和无处不在的正则表达式也是如此。有这么多语言的原因之一是,人们开发了一些工具,非专家也能创建它们。Yacc和Lex正是绝佳例子,它们本身也正是专用语言。
1700437839
1700437840
当然,语言不必非得体现高超科技。史蒂夫·约翰逊仅用一晚时间就打造出第一个版本的at命令:
1700437841
1700437842
“Unix有一种在非上班时间运行计划任务的方法,这样,长时间的任务就不会影响人们的工作(记住,有十几个人共用Unix机器)。要想让任务稍晚再运行,需要编辑系统文件,并以相当晦涩的格式填写信息表。有一天,在与系统文件搏斗时,我听到自己喃喃自语‘我想让这个任务在凌晨2点运行’。突然,我意识到,可以将任务信息归纳为简单的句法:‘at 2AM run_this_command’。我花几个小时就搞出一版,并在第二天早上的‘当日消息’文件中进行了宣传。”
1700437843
1700437844
at命令在40多年后仍在使用,变化不大。如同其他一些语言,其句法是一种像是在大声说话的风格化英语。
1700437845
1700437846
Unix哲学是关于如何处理计算任务的编程风格。这是道格·麦基尔罗伊在《贝尔实验室技术杂志》(Bell Labs Technical Journal)Unix特刊的前言中总结出来的。
1700437847
1700437848
(i)让每个程序做好一件事。要做一件新的工作,就构建新程序,而不是通过增加新“特性”使旧程序复杂化。
1700437849
1700437850
(ii)预期每个程序的输出都能成为另一个未知程序的输入。不要用无关的信息来干扰输出。避免使用严格的分栏对齐或二进制输入格式。不要执着于交互式输入。
1700437851
1700437852
(iii)设计和构建软件,甚至是操作系统,要尽早试用,最好是在几周内就用起来。大刀阔斧砍掉笨拙的部件,重建它们。
1700437853
1700437854
(iv)宁可绕道构建用后即弃的工具来减轻编程负担,也别依赖经验欠奉的帮助。
1700437855
1700437856
这些编程格言并不总被遵守。举例:我在第3章中提到的cat命令。那个命令只做了一件事,把文件输入或标准输入复制到标准输出。今天,GNU版本的cat有(我可没瞎编)12个选项,用于诸如对行编号、显示非输出字符、删除重复空行等任务。所有这些都可以用现有的程序轻松处理。这些选项与复制字节的核心任务无关,而且将基本工具复杂化似乎会适得其反。
1700437857
1700437858
Unix哲学当然不能解决所有编程问题,但它确实为系统设计和实现提供了有益的指导。
1700437859
1700437860
1700437861
1700437862
1700437864
UNIX传奇:历史与回忆 9.2 组织
1700437865
1700437866
我相信,Unix成功的原因还有一大部分来自非技术因素,如贝尔实验室的管理和组织结构,1127中心的人际环境,以及一群人才聚在一起解决不同问题时的思想交流。这些因素比技术概念更难评估,所以必然只能从更为主观的角度来考察。与上一节一样,相关内容大多已在前文提到。
1700437867
1700437868
稳定的环境至关重要:资金、资源、任务、组织结构、管理、文化都应持续和可预测。如第1章所述,贝尔实验室的科研工作是大公司内部大型开发组织的大规模行动,具有悠久历史和明确使命:普遍服务。贝尔实验室的长期目标是不断改进电话服务,这意味着研究人员可以长期甚至年复一年地探索他们认为重要的想法,而不必每隔几个月就向人证明自己在努力。当然也有监督,任何人在一个项目上工作了几年而没有任何成果,都会被要求做出改进。偶尔会有人被调离研究岗位或干脆被赶出公司,但在我15年的管理生涯中,这种情形屈指可数。
1700437869
[
上一页 ]
[ :1.70043782e+09 ]
[
下一页 ]