为什么egrep和grep表现不同,尽管它们是相同的二进制文件?

时间:2012-03-12 05:38:02

标签: bash grep history

$ ls -l /bin/*grep
lrwxrwxrwx 1 root root     4 2010-06-09 02:56 /bin/egrep -> grep
lrwxrwxrwx 1 root root     4 2010-06-09 02:56 /bin/fgrep -> grep
-rwxr-xr-x 1 root root 85060 2007-01-23 02:00 /bin/grep

$ echo 'hello' | grep -q 'l{2}' && echo YES || echo NO
NO

$ echo 'hello' | egrep -q 'l{2}' && echo YES || echo NO
YES

在我的系统中,egrepgrep的符号链接,但它们的行为却不同。为什么呢?

4 个答案:

答案 0 :(得分:3)

grep将通过查看argv[0]来检查其调用。

这是一个简短的演示程序:

> cat someprogram.cpp 
#include <iostream>

int main(int argc, char* argv[])
{
    std::cout << "Shall behave as " << argv[0] << "." << std::endl;
}

构建

> make someprogram
g++ someprogram.cpp   -o someprogram

建立符号链接:

> ln -s someprogram some_other_program

运行一个:

> ./someprogram
Shall behave as ./someprogram.

运行两个:

> ./some_other_program 
Shall behave as ./some_other_program.

Gnu grepfree和开源软件,因此您可以自由查看the source

答案 1 :(得分:2)

因为可执行文件会检查argv[0]的值并相应地调整其行为。

答案 2 :(得分:1)

因为POSIX说egrep相当于grep -E而不是grepfgrep相当于grep -F而不是grep }。如果您希望grep的行为与egrep相同,请使用grep -E,依此类推。还有大约40年的先例问题。

答案 3 :(得分:0)

除正则表达式引擎外,功能相同;通过创建库(这种情况下更常见的方法)或使用检查其名称(argv[0])的单个二进制文件来确定请求的行为,共享代码是有意义的。 (第三种可能性是使用单个名称并使用选项来选择不同的行为。这就是gittar之类的命令;单个命令是“接口”但你得到的通过指定不同的行为来完全不同的行为。)

存在明显命令的原因很长,可以追溯到Unix的早期阶段。简单的旧grep是最早的正则表达式实现之一,随着开发人员对这个特定问题领域的理解得到改进,具有新功能的新工具也得到了发展。出于向后兼容性的原因,这些新功能无法简单地集成到grep(这会改变其行为),因此新命令具有新名称。当POSIX开始标准化时,grepegrepfgrep之间的分工已经确立,尽管事后看来,你可以说至少其中一个是多余的。