Почему egrep и grep ведут себя по-разному, хотя они являются одним и тем же двоичным файлом? - PullRequest
0 голосов
/ 12 марта 2012
$ 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

В моей системе egrep является символической ссылкой на grep, но они ведут себя по-разному. Почему?

Ответы [ 4 ]

3 голосов
/ 12 марта 2012

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 grep является бесплатным и программным обеспечением с открытым исходным кодом, так что вы можете свободно проверять источник .

2 голосов
/ 12 марта 2012

Поскольку исполняемый файл проверяет значение argv[0] и соответствующим образом корректирует его поведение.

1 голос
/ 12 марта 2012

Поскольку POSIX говорит, что egrep эквивалентно grep -E и не является простым grep, а fgrep эквивалентно grep -F и не является простым grep.Если вы хотите, чтобы grep вел себя так же, как egrep, используйте grep -E и так далее.Существует также вопрос о 40-летнем прецеденте.

0 голосов
/ 12 марта 2012

Функциональность идентична, кроме движка регулярных выражений; имеет смысл поделиться кодом, либо создав библиотеку (более распространенный подход в наши дни), либо используя один двоичный файл, который проверяет его имя (argv[0]), чтобы определить, какое поведение запрашивается. (Третья возможность состоит в том, чтобы иметь одно имя и использовать опции для выбора различных поведений, конечно. Это то, что делают команды, такие как git и tar; одна команда - это «интерфейс», но вы получаете совершенно разные поведения при указание различных действий.)

Причиной существования различных команд является долгое наследие, восходящее к ранним временам Unix. Обычная старая версия grep была одной из самых ранних реализаций регулярных выражений, и по мере улучшения понимания разработчиками этой конкретной проблемной области развивались новые инструменты с новыми возможностями. По причинам обратной совместимости эти новые функции нельзя просто интегрировать в grep (это изменило бы его поведение), поэтому новые команды получили новые имена. К тому времени, когда POSIX приступил к стандартизации, разделение труда между grep, egrep и fgrep уже было твердо установлено, хотя в ретроспективе можно утверждать, что по крайней мере один из них является избыточным.

...