打字猴:1.700437799e+09
1700437799
1700437800
1700437801 UNIX传奇:历史与回忆 [:1700434723]
1700437802 UNIX传奇:历史与回忆 9.1 技术方面
1700437803
1700437804 本书前几章已经讨论了来自Unix的重要技术思想,本节做简单总结。当然,并非一切都源于Unix。肯·汤普森和丹尼斯·里奇的部分天才之处在于,他们善于挑选既有的好点子,而且能够洞察普遍概念或统一主题,将软件系统加以简化。人们有时会用代码行数来评价软件的生产力。在Unix的世界里,生产力却往往以删除了多少特殊情况或代码行数来衡量。
1700437805
1700437806 分层文件系统是对既有做法的重大简化,尽管事后看来,它显而易见——你还会想要什么?Unix文件系统提供直截了当的视角:从根目录开始,每个目录要么包含文件的信息,要么包含容纳更多目录和文件的目录信息,而不是由操作系统来管理不同类型文件的属性,也不限制文件在目录中嵌套的深度。文件名只是从根目录开始的路径,各组成部分用斜线隔开。
1700437807
1700437808 文件包含未被解释的字节,系统本身不关心这些字节是什么,也不知道它们的意义。
1700437809
1700437810 文件的创建、读取、写入和删除只需六七个系统调用即可完成。屈指可数的权限位定义了访问控制,能够满足大多数目的。像可移动磁盘这样的存储设备可以挂载在文件系统上,从逻辑上讲,就成了文件系统的一部分。
1700437811
1700437812 自然,也有一些不规范的地方。让设备出现在文件系统中是一种简化做法,但对它们的操作,尤其是对终端的操作,会有特殊情况,接口混乱的状况延续至今。
1700437813
1700437814 我指的是文件系统的逻辑结构。有很多方法可以实现这个模型,事实上,现代系统支持各种各样的实现,呈现出相同接口,但用不同的代码和内部数据结构来实现。看看你的计算机,你会看到有多种设备使用这种模式:硬盘、U盘、SD卡、相机、手机等。Unix的高明之处在于选择了足够普适的抽象概念,既能发挥巨大的作用,又不至于在性能上付出太大代价。
1700437815
1700437816 高层级的实现语言当然是为用户程序服务的,但也是为操作系统本身服务的。这个想法并不新鲜:它已经在Multics和几个早期的系统中尝试过,但时机和语言都尚未完全准备好。C语言比它的前辈们更适合,它让操作系统具备可移植性。曾几何时,世上只有硬件制造商的专有操作系统,配备专有语言,而Unix则成为开放的、被广泛理解的标准,然后变作一种商品:系统只需稍加改动就可在所有计算机上使用。客户不再被束缚在特定硬件上,制造商也不再需要开发自己的操作系统或语言。
1700437817
1700437818 用户级的可编程shell具有控制流语句和方便的I/O重定向功能,使得将程序作为构件进行编程成为可能。随着shell编程能力的增强,它成为程序员工具箱中的另一种高级语言。而且,因为它是用户级程序,不是操作系统的一部分,所以任何人只要有更好的想法,就可以对它进行改进和替换。从最初的Unix shell到PWB、伯恩的shell和比尔·乔伊的csh,再到今天百花齐放,说明了它的好处,当然也有一些缺点——太容易繁殖出互不兼容的版本。
1700437819
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)让每个程序做好一件事。要做一件新的工作,就构建新程序,而不是通过增加新“特性”使旧程序复杂化。
[ 上一页 ]  [ :1.700437799e+09 ]  [ 下一页 ]