Linux 和其他类 UNIX 系统总是附带了大量的工具,它们执行从显而易见的到不可思议的广泛功能。类 UNIX 编程环境的成功很大程度上归功于工具的高品质和选择,以及这些工具之间相互衔接的简易性。
作为开发人员,您可能会发现现有实用程序并不总是能够解决问题。虽然能够通过结合使用现有实用程序来容易地解决许多问题,然而解决其他问题却至少需要一些实际的编程工作。这些后面的任务通常是创建新实用程序的候选任务,结合现有实用程序来创建新实用程序可以通过做最少的工作来解决问题。本文考察优秀实用程序所具有的品质,以及设计这种实用程序所经历的过程。
优秀的实用程序具有哪些品质?
优秀的实用程序是把自己的工作做得尽可能好的实用程序。它必须与其他实用程序配合融洽;必须能够容易地与其他实用程序结合使用。无法与其他实用程序结合使用的程序不是实用程序,而是应用程序。
实用程序应该允许您根据手边的材料廉价而容易地构建一次性的应用程序。许多人认为实用程序就像是工具箱中的工具。设计实用程序的目标不是为了让单个工具来做所有事情,而是为了拥有一组工具,其中每个工具都尽可能好地做一件事情。
有些实用程序自身就是相当有用的,而其他实用程序则必须与一系列实用程序配合使用。前者的例子包括 sort 和 grep。另一方面,xargs 除了与其他实用程序(最常见的是 find)配合使用外,很少单独使用。
使用什么语言来编写实用程序?
大多数 UNIX 系统实用程序都是用 C 语言来编写的。本文中的例子使用 Perl 和 sh。应该使用恰当的工具来做恰当的事情。如果您对某个实用程序使用得足够频繁,那么用编译型语言来编写它的成本也许能通过性能提升来获得回报。另一方面,对于程序的工作负荷很轻这种相当普遍的情况,使用脚本语言也许会提供更快的开发速度。
如果无法肯定,您应该使用自己最了解的语言。至少当您在对某个实用程序进行原型化,或在弄清它是如何有用时,程序员效率将优先于性能调整。大多数 UNIX 系统实用程序都是用 C 编写的,这只是因为这些实用程序使用得足够频繁,以致考虑效率比考虑开发成本更加重要。Perl 和 sh(或 ksh)可能是用于快速原型化的很好语言。对于与其他程序配合实用的实用程序,使用 shell 来编写它们或许要比使用更传统的编程语言来编写它们要容易一些。另一方面,当您希望与原始的字节交互时,C 或许就是最好的选择。
设计实用程序
一个不错的经验法则就是当您第二次必须解决某个问题时,首先考虑实用程序的设计。不要对第一次编写的一次性作品感到遗憾;您可以将它看作是一个原型。第二次,请把您所需的功能与第一次所需的功能作比较。在第三次前后,您应该开始考虑花时间来编写一个通用实用程序。即使纯粹的重复性任务也可能会给实用程序的开发带来好处;例如,由于人们对尝试以通用的方式重命名文件感到失望,于是开发了许多通用文件重命名程序。
下面是一些实用程序设计目标;每个目标将在下面单独的小节中介绍。
●做好一件事情。
●成为一个过滤器。
●通用化。
●健壮。
●新颖。
●做好一件事情
做好一件事情;不要糟糕地做多件事情。关于做好一件事情的最佳例子或许是 sort。除了 sort 外,没有其他 哪个实用程序具有排序功能。基本的思想很简单:如果一次仅解决一个问题,您就能花时间把它解决好。