我们每天都在使用前人开发的各种工具。一款好的工具能无缝地融入到你的工作环境中,而一款“差”的工具常常需要花费额外的精力才能集成到你的工作环境中。(注意:这里的差是指用户体验方面的问题,但这些工具本身还是有用的)。作为工程师,我们总是需要开发一些工具给自己或者给别人用。Marius Eriksen的这篇文章(http://monkey.org/~marius/unix-tools-hints.html)讲了设计Unix工具需要注意的地方。需要说明的是,这篇文章讲的是开发Unix工具方面的建议,主要是使之能很好地和经典的Unix工具能很好地集成在一起,所以里面的建议可能不适用于别的场景。本文把Marius的文章简单总结了一下,以飨读者。
一、从标准输入(stdin)中读取数据,将结果输出到标准输出(stdout)。
换种说法,你的工具应该是个过滤器,从而它能很容易地被集成到shell的管道中去,就能和Unix的很多工具在一起工作了。
二、输出的结果中最好不要有header或者其他装饰性输出
如果使用你工具的人需要解析工具的输出结果,输出结果中包含太多这种装饰性输出会使得解析工作变得复杂。
三、输出的结果要能容易解析
结果中的每条记录最好是单行,纯文本的输出,每条记录中的列用空格或者TAB分割(请不要用JSON格式输出)。因为那些经典的Unix工具,比如sort,grep,sed都是假定输入是这种格式的。
四、把工具的输出看成是工具的API
对API来讲,很重要的一点就是要保持其稳定性。如果你的工具的输出格式变化了的话,其他依赖于你的工具就可能挂掉。
五、把诊断信息输出到标准错误(stderr)
诊断信息包括进度信息,调试信息,日志,错误和使用方法,这些信息不是你工具的主要输出信息。如果诊断信息和数据混在一起的话,会使得工具的输出结果难以解析。把诊断信息输出到stderr的另外一个好处是,当你对数据进行过滤或者重定向的时候,这些诊断信息还是会完整地输出到屏幕上。
六、用退出状态码来标记错误
如果你的工具运行失败了,应当把退出状态码设为一个非0值。这使得你的工具能够很好地和别的脚本集成在一起。我想这点应该是没有争议的。
七、输出内容中尽量包含完整信息
输出内容中不可避免地会包含一些上下文或者环境信息,比如机器名,文件路径等。好的工具的输出应尽量提供完整的信息,比如用绝对路径和FQDN。这样就只需要少的上下文信息就能理解输出内容了。比如,如果输出包含文件的相对路径,那么就需要知道当前的工作目录是什么才能知道对应的文件在哪里。
八、避免过多无用的诊断信息
不要在正常的情况下输出过多的诊断信息。如果非要这样的话,把诊断信息输出到stderr,同时放在verbose模式,默认不开启verbose模式。
九、避免用户交互
好的工具应当避免用户交互,这使得工具能够被cron调度,或者在远程机器上执行。需要交互的工具会非常难以地和其他工具集成。如果非要提供交互模式,请也一定提供silent模式。
需要用户交互的场景可能有让用户确认一个危险的操作,在这种情况下可以让用户指定一个特定的参数,比如git中删除一个branch是用git branch -d。当branch上有commit没有合并的时候,想要强制删除分支就要用git branch -D。
可以看到,上面的建议主要是关注在如何使得工具能和别的工具整合在一起是用,如何使得工具的输出能更好地被解析。如果在开发工具的时候考虑这些建议,你的工具会更优秀。
如果想了解最新的技巧,请关注微信公众号“工程师的那些事”