2012-03-12 20 views
0
$ 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的符號鏈接,但它們的行爲不同。爲什麼?爲什麼egrep和grep的行爲不同,儘管它們是相同的二進制文件?

回答

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

2

由於可執行程序檢查argv[0]的值並相應地調整其行爲。

1

因爲POSIX說,egrep相當於grep -E,而不是普通的grep,並fgrep相當於grep -F,而不是普通的grep。如果要使grep的行爲與egrep的行爲相同,請使用grep -E,依此類推。還有約40年的先例問題。

0

除正則表達式引擎外,其功能相同;通過創建一個庫(目前比較常用的方法)或者使用一個檢查其名稱(argv[0])的單個二進制來確定請求哪個行爲來共享代碼是有意義的。 (第三種可能是使用單個名稱和使用選項來選擇不同的行爲,這就是gittar這樣的命令;單個命令是「界面」,但是通過指定不同的操作可以獲得大不相同的行爲。 )

有不同的命令的原因是一個悠久的遺產,可以追溯到Unix的早期。簡單的舊grep是正則表達式的最早實現之一,隨着開發人員對這個特定問題領域的理解得到改進,具有新功能的新工具不斷髮展。出於向後兼容的原因,這些新功能不能簡單地集成到grep(這會改變它的行爲),因此新命令有新名稱。到POSIX開始規範事情時,grep,egrepfgrep之間的分工已經確立,儘管事後看來,你可能會爭辯說至少有一個是多餘的。

相關問題