kev
kev

Reputation: 161664

Why do egrep and grep behave differently although they are the same binary?

$ 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

In my system, egrep is a symbolic link to grep, but they behave differently. Why?

Upvotes: 0

Views: 241

Answers (4)

tripleee
tripleee

Reputation: 189367

The functionality is identical apart from the regex engine; it makes sense to share the code, either by creating a library (a more common approach these days) or by using a single binary which examines its name (argv[0]) to determine which behavior is requested. (A third possibility is to have a single name and use options to select different behaviors, of course. This is what commands like git and tar do; a single command is the "interface" but you get vastly different behaviors by specifying different actions.)

The reason there are distinct commands is a long legacy, going back to the early days of Unix. Plain old grep was one of the earliest implementations of regular expressions, and as the developers' understanding of this particular problem domain improved, new tools with new capabilities evolved. For reasons of backwards compatibility, these new features could not simply be integrated to grep (this would have changed its behavior) so the new commands had new names. By the time POSIX got around to standardizing things, the division of labor between grep, egrep and fgrep was firmly established, although in hindsight, you could argue that at least one of them is redundant.

Upvotes: 0

johnsyweb
johnsyweb

Reputation: 141790

grep will check its invocation by looking at argv[0].

Here's a short program to demonstrate:

> cat someprogram.cpp 
#include <iostream>

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

Build:

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

Make a symbolic link:

> ln -s someprogram some_other_program

Run one:

> ./someprogram
Shall behave as ./someprogram.

Run two:

> ./some_other_program 
Shall behave as ./some_other_program.

Gnu grep is free and open source software, so you are free to examine the source.

Upvotes: 4

Jonathan Leffler
Jonathan Leffler

Reputation: 753655

Because POSIX says that egrep is equivalent to grep -E and not plain grep, and fgrep is equivalent to grep -F and not plain grep. If you want grep to behave the same as egrep, use grep -E, and so on. There is also the issue of about 40 years of precedent.

Upvotes: 1

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798606

Because the executable checks the value of argv[0] and adjusts its behavior accordingly.

Upvotes: 2

Related Questions