膨胀的回声命令

时间:2010-07-20 13:57:49

标签: gnu freebsd openbsd netbsd dragonfly-bsd

查看“echo”命令的以下实现:

当你从列表中走下去时,我确信你会发现每个实现中的膨胀都在增加。 272行回声程序有什么意义?

3 个答案:

答案 0 :(得分:14)

在他们的文章“UNIX环境中的程序设计”中,Pike& Kernighan讨论cat程序如何增加控制参数。在某个地方,虽然不是那篇文章,但有一条关于“cat从伯克利挥舞旗帜回来的评论”。这与echo开发选项的问题类似。 (我发现了对cat的BSD(Mac OS X)手册页中的相关文章的引用:Rob Pike,“UNIX Style,或者cat -v Considered Harmful”,USENIX Summer会议论文集,1983年。另见http://quotes.cat-v.org/programming/

在他们的书“The UNIX Programming Environment”中,Kernighan&派克(是的,那两个人再次引用道格麦克罗伊关于“回声”应该做什么没有争论的主题(大约1984年):

  

哲学的另一个问题是echo如果没有参数则应该做什么 - 具体来说,它应该打印一个空行还是什么都没有。我们所知道的所有当前echo实现都打印出一个空白行,但过去的版本没有,并且就此主题进行了很多争论。道格麦克罗伊在讨论这个话题时传授了正确的神秘主义感受:

UNIX和Echo

  

在新泽西州居住着UNIX,这是一位公平的女仆,他们的学生们远远地去钦佩。由于她的纯洁而感到眼花缭乱,所有人都试图支持她,一个是为了她的处女恩典,另一个是为了她的文明,而另一个因为她在执行严格的任务方面的敏捷性,即使在更富裕的土地上也很少完成。如此庞大的内心和适应自然的是,UNIX采用了除了最富裕的追求者之外的所有人。很快,许多后代成长并繁荣并扩散到地球的尽头。

     

大自然亲自微笑,并且比其他凡人更热切地回答UNIX。那些不太懂礼貌的谦卑民众对她的回声很高兴,如此精确而清晰,他们很少相信她可以被同样的岩石和树林所回答。兼容的UNIX必须完美回应她所要求的任何内容。

     

当一个不耐烦的swain向UNIX询问“没有回声”时,UNIX有义务地张开嘴,没有回应,并再次关闭它。

     

'你的意思是什么,'年轻人要求',这样张开嘴?从此以后,当你不应该回声时,永远不要张开嘴! UNIX迫不及待。

     “但是我想要一个完美的表演,即使你什么都不回应,”一位敏感的年轻人恳求道,“闭嘴不能发出完美的回声。”不想得罪任何一个,UNIX同意对不耐烦的年轻人和麻木不仁的年轻人说不同的话。她称敏感没有'\n'。

     

然而现在,当她说'\n'时,她并没有真正说什么,所以她不得不两次张开嘴,一次说“\n”,一次不说,所以她并没有让敏感的年轻人满意,他们立刻说,“\n听起来对我来说完全没什么,但第二个却毁了它。我希望你收回他们中的一个。所以无法忍受犯罪的UNIX同意撤消一些回声,称之为“\c”。现在敏感的年轻人可以通过一起要求“\n”和“\c”来听到完美的回音。但是他们说他在听过之前就已经因为过多的记谱而死了。


Korn shell引入了(或至少包含)基于C语言printf函数的printf()命令,并使用格式字符串来控制材质的显示方式。与echo相比,它是复杂格式化的更好工具。但是,由于引文中概述的历史,echo不仅仅是回应;它解释了回应的内容。

将命令行参数解释为echo无疑需要更多代码而不是解释它们。基本的echo命令是:

#include <stdio.h>
int main(int argc, char **argv)
{
    const char *pad = "";
    while (*++argv)
    {
        fputs(pad, stdout);
        fputs(*argv, stdout);
        pad = " ";
    }
    fputc('\n', stdout);
    return 0;
}

还有其他方法可以实现这一目标。但更复杂的echo版本必须在打印任何内容之前仔细检查它们的参数 - 这需要更多的代码。并且不同的系统已经决定他们想要对他们的参数进行不同数量的解释,从而导致不同数量的代码。

答案 1 :(得分:7)

你会发现实际上并没有那么多膨胀。

  1. 大部分代码都是注释。
  2. 大多数不是注释的代码行都是用法文档,因此当有人使用'echo --help'它会做一些事情。
  3. 上面的代码主要是处理echo可以采用的参数,以及\ n和\ t等符号的“特殊”扩展是它们的等效字符,而不是字面上回显它们。
  4. 此外,大多数情况下,你甚至没有运行echo命令,大多数时候'echo'会调用内置的shell。至少在我的机器上,您必须输入/bin/echo --help才能获得所有高级功能/文档,因为echo --help只是回显--help

    举个好例子,在shell中运行它。

     echo '\e[31mhello\e[0m'
    

    然后运行:

     echo -e '\e[31mhello\e[0m'
    

    你会注意到截然不同的结果。

    前者只是按原样发出输入,但后者会打印hello红色。

    另一个例子,使用'十六进制'代码:

    $echo '\x64\x65\x66'
    \x64\x65\x66
    
    $echo -e '\x64\x65\x66'
    def
    

    极不同的行为。 openbsd实现不能这样=)。

答案 2 :(得分:1)

我不确定我是否喜欢第一个实现:它有一个选项太多了!

如果需要-n选项,那么添加--选项以停止选项处理会很有帮助。这样,如果您正在编写一个读取和打印用户输入的shell脚本,那么如果用户键入-n,则不会出现不一致的行为。