设想一下,如果大多数程序都具有排序功能,但是有些仅支持按词法排序,而其他一些仅支持按数字排序,另外一些甚至支持关键字选择而不是对整行排序,那将是一件多么令人沮丧的事情 。起码,这也是恼人的 。
当您发现某个问题需要解决时,应尝试将问题分解为多个部分,不要重复那些其他实用程序中已经存在的部分 。您对允许配合现有工具使用的工具关注得越多,您的实用程序就越有可能保持有用 。
也许您需要编写多个程序 。完成专门任务的最佳途径通常是编写一两个实用程序,再用一些线索将它们联系起来,而不是编写单个程序来解决整件事情 。使用 20 行的 shell 脚本来将新的实用程序与现有工具结合起来是很理想的 。如果尝试一次解决整个问题,随之而来的第一个变更就可能要求您全盘重新考虑 。
我偶尔需要从数据库生成两列或三列的输出 。编写一个程序在单个列中生成输出,然后结合使用一个对输出进行分列的程序,这样通常会更有效率 。组合这两个实用程序的 shell 脚本本身是临时性的,单独的实用程序比这个脚本的使用寿命更长 。
有些实用程序服务于非常专一的需要 。针对一个包含大量内容的目录,如果 ls 的输出非常快地滚出屏幕,这可能是因为其中有一个文件具有非常长的文件名,从而迫使 ls 仅对输出使用单个列 。使用 more 来对输出分页会花一些时间 。为什么不像下面这样就按长度对行排序,然后通过 tail 来管道输出结果呢?
清单 1. 世间能找到的最小实用程序 sl
#/usr/bin/perl -w
print sort { length $a <=> length $b } <>;
清单 1 中的脚本确切地就做一件事情 。它不接受任何选项,因为它不需要选项;它仅关心行的长度 。归功于 Perl 便利的 <> 表达方式,这个小实用程序既适用于标准输入,也适用于命令行指定的文件 。
成为一个过滤器
几乎所有实用程序都最适合想像为过滤器,尽管有一些非常有用的实用程序不符合这个模型 。(例如,某个程序在执行计数时可能非常有用,尽管它作为过滤器工作得并不好 。仅接受命令行参数作为输入并潜在地产生复杂输出的程序可能非常有用 。)然而,大多数实用程序都应该作为过滤器来工作 。根据惯例,过滤器对文本的行起作用 。大多数过滤器都应该支持多个输入文件 。
记住实用程序需要在命令行和脚本中运行 。有时,理想的行为会稍有不同 。例如,大多数版本的 ls 都会在向终端写出时自动将输入排序到多个列中 。grep 的默认行为是在指定多个文件的情况下打印从其中找到匹配项的那个文件名称 。这样的差别应该与用户希望的实用程序工作方式有关,而不是与其他事项有关 。例如,旧版本的 GNU bc 在启动时显示强迫性的版权标记 。请不要那样做 。让您的实用程序仅做它应该做的事情 。
实用程序喜欢生活在管道中 。管道允许实用程序专注于自己的工作,而不是去关注旁枝末节 。为了生活在管道中,实用程序需要从标准输入读取数据,然后向标准输出写出数据 。如果您希望处理记录,那么您最好能够使每一行成为一个“记录” 。诸如 sort 和 join 之类的现有程序已经在那样考虑了 。它们将会因为您这样做而感谢您 。
我偶尔使用这样一个实用程序,它针对一个文件树反复调用其他程序 。这充分利用了标准的 UNIX 实用程序过滤器模型,但是该模型仅适用于读取输入然后写出输出的实用程序;不能将它用于就地操作或接受输入输出文件名的实用程序 。
可以使用标准输入来运行的大多数程序也完全可以针对单个文件或一组文件运行 。注意,可以证明这样违背了反对重复工作的规则;显而易见,这可以通过将 cat 的输出馈送给该系列中的下一个程序来解决 。然而这在实践中似乎是合理的 。
推荐阅读
- 安装显卡好简单
- lilo/grub linux忘记了密码怎么办
- vmware 配置实例-linux host + windows guest + fire
- Linux 内核的类型
- 其它 Linux 常用命令
- 改变文件或目录的访问权限 Linux 常用命令
- 备份与压缩 Linux 常用命令
- 在Linux环境下运行DOS命令 Linux 常用命令
- 入门:Linux 2.6 内核的嵌入式系统应用
- 安装过Windows的电脑上如何安装Linux