Reputation: 161664
$ 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
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
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
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
Reputation: 798606
Because the executable checks the value of argv[0]
and adjusts its behavior accordingly.
Upvotes: 2