9

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

当您查看列表时,我相信您会注意到每个实现中的膨胀越来越大。272 行回显程序的意义何在?

4

3 回答 3

14

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

在他们的《UNIX 编程环境》一书中,Kernighan 和 Pike(是的,又是那两个)引用了 Doug McIlroy 关于“echo”应该在没有参数的情况下做什么(大约 1984 年)的主题:

另一个哲学问题是echo如果没有参数应该怎么做 - 具体来说,它应该打印一个空行还是什么都不打印。我们所知道的所有当前echo实现都会打印一个空白行,但过去的版本没有,并且关于这个主题存在很大的争论。道格麦克罗伊在他关于这个话题的讨论中传达了正确的神秘主义感觉:

UNIX 和 Echo

UNIX 居住在新泽西州的土地上,是一位美丽的女仆,学者们不远万里慕名而来。所有人都为她的纯洁而眼花缭乱,都想拥护她,一个是因为她处女般的优雅,另一个是因为她优雅的文雅,还有一个是因为她敏捷地执行即使在更富裕的土地上也很少完成的艰巨任务。她心胸宽广,天性随和,以至于 UNIX 采用了所有追求者,除了最令人难以忍受的有钱的追求者。很快,许多子孙繁衍生息,遍及天涯海角。

与其他凡人相比,大自然本身对 UNIX 微笑和回答更热切。谦逊的人,对更礼貌的举止知之甚少,对她的回声感到高兴,如此精确和水晶般清晰,他们几乎不相信同样的岩石和树林会回应她,这些岩石和树林在旷野中如此混乱地喊叫。无论她被问什么,兼容的 UNIX 都会完美回应。

当一位不耐烦的小伙子问 UNIX,“无回声”时,UNIX 顺从地张开嘴,没有回声,然后又闭上了。

“不管你是什么意思,”年轻人问道,​​“就这样张开嘴?从此以后,当你应该什么都不回应的时候,永远不要开口!UNIX 有义务。

“但我想要一场完美的表演,即使你什么都没有回应,”一个敏感的年轻人恳求道,“闭上的嘴巴也不会发出完美的回应。” UNIX 不想冒犯任何一方,同意对不耐烦的年轻人和麻木不仁的年轻人说不同的话。她把敏感的无所谓' \n'。

可现在她说‘ \n’的时候,并不是真的什么都没说,所以她不得不张开嘴两次,一次是说‘ \n’,一次是什么都不说,所以她并没有取悦敏感的年轻人,她马上说:‘\n对我来说听起来像是一个完美的虚无,但第二个毁了它。我要你收回其中一个。于是 UNIX 忍不住得罪了,同意撤消一些回声,并称其为 ' \c'。\n现在敏感的年轻人可以通过同时要求“ ”和“ ”来听到完美的回声\c。但是他们说他在听过一个音符之前就死于符号过多。


Korn shell 引入(或至少包括)一个printf基于 C 语言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必须在打印任何东西之前仔细检查他们的论点——这需要更多的代码。并且不同的系统已经决定他们想要对其参数进行不同数量的解释,从而导致不同数量的代码。

于 2010-07-20T15:28:03.287 回答
8

您会注意到实际上并没有那么大的膨胀增长。

  1. 大多数代码行都是注释。
  2. 大多数不是注释的代码行都是使用文档,所以当有人去'echo --help'时它会做一些事情。
  3. 上述代码之外的代码似乎主要是处理 echo 可以采用的参数,以及将 \n 和 \t 等符号的“特殊”扩展作为它们的等效字符,而不是按字面意思回显它们。

此外,大多数时候,您甚至没有运行 echo 命令,大多数时候 'echo' 会调用内置的 shell。至少在我的机器上,您必须输入/bin/echo --help才能从中获取所有高级功能/文档,因为echo --help只有 echo 的--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 的实现不能这样=)。

于 2010-07-20T14:01:36.897 回答
1

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

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

于 2011-02-22T10:11:55.707 回答