随着时间的流逝,人们开发出了一套设计与编写软件工具的原则。在本书用来解决问题的程序中,你将会看到这些原则的应用示例。好的软件工具应该具备下列特点:
一次做好一件事
在很多方面,这都是最重要的原则。若程序只做一件事,那么无论是设计、编写、调试、维护,以及生成文件都会容易得多。举例来说,对于用来查找文件中是否有符合样式的grep程序,不应该指望用它来执行算术运算。
这个原则的结果,自然就是会不断产生出更小、更专用于特定功能的程序,就像专业木匠的工具箱里,永远会有一堆专为特定用途所设计的工具。
处理文本行,不要处理二进制数据
文本行是UNIX的通用格式。当你在编写自己的工具程序时便会发现,内含文本行的数据文件很好处理,你可以用任何唾手可得的文本编辑器来编辑它,也可以让这些数据在网络与各种机器架构之间传输。使用文本文件更有助于任何自定义工具与现存的UNIX程序之间的结合。
使用正则表达式
正则表达式(regular expression)是很强的文本处理机制。了解它的运作模式并加以使用,可适度简化编写命令脚本(script)的工作。
此外,虽然正则表达式多年来在工具与UNIX版本上不断在变化,但POSIX标准仅提供两种正则表达式。你可以利用标准的库程序进行模式匹配的工作。这样就可以编写出专用的工具程序,用于与grep一致的正则表达式(POSIX称之为基本型正则表达式,Basic Regular Expressions,BRE),或是用于与egrep一致的正则表达式(POSIX称之为扩展型正则表达式,Extended Regular Expressions,ERE)。
默认使用标准输入输出
在未明确指定文件名的情况下,程序默认会从它的标准输入读取数据,将数据写到它的标准输出,至于错误信息则会传送到标准错误输出(这部分将于第2章讨论)。以这样的方式来编写程序,可以轻松地让它们成为数据过滤器(filter),例如,组成部分的规模越大,越需要复杂的管道(pipeline)或脚本来处理。
避免喋喋不休
软件工具的执行过程不该像在"聊天"(chatty)。不要将"开始处理"(starting processing)、"即将完成"(almost done)或是"处理完成"(finished processing)这类信息放进程序的标准输出(至少这不该是默认状态)。
当你有意将一些工具串成一条管道时,例如:
1. tool_1 datafile tool_2 tool_3 tool_4 resultfile
若每个工具都会产生"正处理中"(yes I‘m working)这样的信息并送往管道,那么别指望执行结果会像预期的一样。此外,若每个工具都将自己的信息传送至标准错误输出,那么整个屏幕画面就会布满一堆无用的过程信息。在工具程序的世界里,没有消息就是好消息。
这个原则其实还有另外一个含义。一般来说,UNIX工具程序一向遵循"你叫它做什么,你就会得到什么"的设计哲学。它们不会问"你确定吗?"(are you sure)这种问题,当用户键入rm somefile,UNIX的设计人员会认为用户知道自己在做什么,然后毫无疑问地rm删除掉要删除的文件(注5)。
输出格式必须与可接受的输入格式一致
专业的工具程序认为遵循某种格式的输入数据,例如标题行之后接着数据行,或在行上使用某种字段分隔符等,所产生的输出也应遵循与输入一致的规则。这么做的好处是,容易将一个程序的执行结果交给另一个程序处理。
举例来说,netpbm程序集(注5)是用来处理以Portable BitMap(PBM)格式保存的图像文件(注6)。这些文件内含bitmapped图像,并使用定义明确的格式加以绘制。每个读取PBM文件的工具程序,都会先以某种格式来处理文件内的图像,然后再以PBM的格式写回文件。这么一来,便可以组合简单的管道来执行复杂的图像处理,例如先缩放影像后,再旋转方向,最后再把颜色调淡。
让工具去做困难的部分
虽然UNIX程序并非完全符合你的需求,但是现有的工具或许已经可以为你完成90%的工作。接下来,若有需要,你可以编写一个功能特定的小型程序来完成剩下的工作。与每次都从头开始来解决各个问题相比,这已经让你省去许多工作了。
构建特定工具前,先想想
如前所述,若现存系统里就是没有需要的程序,可以花点时间构建满足所需的工具。然而,动手编写一个能够解决问题的程序前,请先停下来想几分钟。你所要做的事,是否有其他人也需要做?这个特殊的工作是否有可能是某个一般问题的一个特例?如果是的话,请针对一般问题来编写程序。当然,这么做的时侯,无论是在程序的设计或编写上,都应该遵循前面所提到的几项原则。

摘自:《shell脚本学习指南》

通过学习本书,你不仅能了解UNIX工具集,还能吸收到UNIX的中心思想与软件工具设计的原则。

shell软件工具设计的原则_转的更多相关文章

  1. SMART原则_百度百科

    SMART原则_百度百科 SMART原则

  2. Java-异常机制详解以及开发时异常设计的原则要求

    Java-异常机制详解以及开发时异常设计的原则要求 http://blog.csdn.net/Jack__Frost/article/details/52760930?locationNum=6

  3. Java开发设计——七大原则

    Java开发设计——七大原则 摘要:本文主要介绍了在做面向对象开发时要注意的七个原则. 部分内容来自以下博客: https://www.cnblogs.com/xiyuekamisama/p/1057 ...

  4. 访客至上的Web、移动可用性设计--指导原则

    文章出自:听云博客 关于可用性设计,之前写过一个“纸上谈兵”版本的,那篇帖子主要是根据A/B test的方式来进行的. 但是最近找了本Steve krug写的Don't make me think,我 ...

  5. 扁平化设计五大原则(转自CSDN翻译)

    Cousins表示他虽然对扁平化设计的感觉非常强烈,但并没有特别热爱或者特别讨厌扁平化设计.他认为好的设计不应当局限于某种设计风格,而需要更注重可用性.有用性.如果因为时尚的缘故,那就顺其自然吧.但该 ...

  6. OO设计原则 -- OO设计的原则及设计过程的全面总结

    这部分增加一点自己的感想,OO设计原则下面讲述的很清晰;看完之后有点感想如果我们在实际开发当中能够把这些原则熟烂于心的话那我们的代码质量和个人能力会有很显著的提神.根据自己的实际经验看很多开发者在开发 ...

  7. 【设计模式系列】之OO面向对象设计七大原则

    1  概述 本章叙述面向向对象设计的七大原则,七大原则分为:单一职责原则.开闭原则.里氏替换原则.依赖倒置原则.接口隔离原则.合成/聚合复用原则.迪米特法则. 2  七大OO面向对象设计 2.1 单一 ...

  8. PHP面向对象设计五大原则(SOLID)梳理总结

    PHP设计原则梳理,参考<PHP核心技术与最佳实践>.<敏捷开发原则.模式与实践>,文章PHP面向对象设计的五大原则.设计模式原则SOLID 单一职责原则(Single Res ...

  9. Restful API 架构与设计参考原则

    1. 什么是RESTREST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. 它首次出现在2000年Roy Fielding的博 ...

随机推荐

  1. Asp.Net:GridView 编辑、删除、自定义分页以后备用

    页面 GridView 绑定:在中,有 <asp:BoundField/>和 <asp:TemplateField><ItemTemplate>嵌套服务器控件 &l ...

  2. SQLServer组件

    1.客户端 2.协议层 3.查询处理器 4.存储引擎 5.数据库操作系统 如下图:

  3. 点击li标记中的<a>标记改变li背景图片怎样实现

    <div class="nav"><ul><li id="li1" class="dianji" onclic ...

  4. OpenGL EXT: shader_buffer_load

    http://www.opengl.org/registry/specs/NV/shader_buffer_load.txt Overview At a very coarse level, GL h ...

  5. 【转载】Linux系统与性能监控

    原文地址:http://kerrigan.sinaapp.com/post-7.html Linux System and Performance Monitoring http://www.hous ...

  6. mysql操作类库--摘抄

    <!--?php /** +---------------------------------- * MySQL操作类库 +---------------------------------- ...

  7. MySQL字段之集合(set)枚举(enum)

    MySQL字段之集合(set)枚举(enum) (2008-12-23 13:51:23) 标签:it  分类:MySQL 集合 SET mysql> create table jihe(f1 ...

  8. Apache Kafka源码分析 - PartitionStateMachine

    startup 在onControllerFailover中被调用, initializePartitionState private def initializePartitionState() { ...

  9. (转)Linux下安装Matlab2014及破解

    原文链接:http://blog.csdn.net/lanbing510/article/details/41698285 文章已搬家至http://lanbing510.info/2014/12/0 ...

  10. .Net Install类的Install、Commit等事件触发顺序

    .Net Install类的Install.Commit等事件触发顺序 空间   首先是Install其中调用base.Install过程中导致OnBeforeInstallOnAfterInstal ...