2015-01-13 33 views
4

我在Bash shell腳本中編寫了一個函數來搜索Linux樹中與包含正則表達式的模式相匹配的文件名,顏色突出顯示:Bash shell腳本函數提供了「find:缺少參數到`-exec'」錯誤

function ggrep { 
LS_="ls --color {}|sed s~./~~" 
[ -n "$1" -a "$1" != "*" ] && NAME_="-iname $1" || NAME_= 
[ -n "$2" ] && EXEC_="egrep -q \"$2\" \"{}\" && $LS_ && egrep -n \"$2\" --color=always \"{}\"|sed s~^B~\ B~" || EXEC_=$LS_ 
FIND_="find . -type f $NAME_ -exec sh -c \"$EXEC_\" \\;" 
echo -e \\e[7m $FIND_ \\e[0m 
$FIND_ 
} 

eg ggrep a*列出所有文件開始與當前目錄樹下a

和文件的ggrep a* x名單開始a和含x

當我運行它,我得到:

find: missing argument to `-exec' 

即使我當我通過「echo」將行輸出複製並粘貼到終端中時,獲得正確的輸出。任何人都可以告訴我我做錯了什麼嗎?

其次,如果ggrep * x列出包含x所有文件,但*擴展到文件名列表,我需要使用\*'*'而是將是巨大的。有沒有解決的辦法?謝謝!

+0

作爲一般規則,將命令作爲字符串放入shell變量並稍後運行會導致很多引用的痛苦。我會建議找到解決問題的另一種方法。如果您必須將命令存儲在變量中,請使用[arrays](http://www.thegeekstuff.com/2010/06/bash-array-tutorial/)。 –

回答

1
eval $FIND_ 

函數體中的最後一行對我來說工作正常。

BASH中的擴展一般不是遞歸的,所以如果你從變量中加載一個命令,你應該總是使用「eval」來強制重新處理擴展變量,因爲它是一個新輸入。通常情況下,引號在已擴展的字符串中處理不當。

對於你的第二個問題,我認爲沒有令人滿意的解決方案。在將它傳遞給你控制的任何東西之前,外殼總是會展開。您可以禁用此擴展,但這是一個全局設置。無論如何,我認爲這種擴張實際上可以有利於你的功能。考慮以利用它的方式重寫它。 (我沒有分析當前版本是否接近。)

+0

幹得好,Tomasz:eval解決了問題!也感謝解釋*擴展。猜猜我必須使用不同的符號來保存一些輸入... – Gnubie

2

\;而不是\\;終止find命令。

find . -type f $NAME_ -exec sh -c \"$EXEC_\" \; 
+0

謝謝,Avinash,但我得到了同樣的錯誤。事實上,從1到4(含)反斜槓給出了相同的結果(也是相同的回波輸出)。當然是 – Gnubie

+0

。你在引用內部執行它,所以根本不需要逃避';'。 –

+0

謝謝,Karoly。沒有反斜槓給出樹中每個文件的「--color:1:--color:Syntax error:Unterminated quoted string」。 – Gnubie