Bash
使用參數列表呼叫另一個函式的函式不起作用
在我的 .bash_aliases 中,我定義了一個從命令行使用的函式,如下所示:
search -n .cs -n .cshtml -n .html SomeTextIWantToSearchFor /c/code/website/ /c/stuff/something/whatever/
該函式建構了一個 grep 命令,將結果通過管道傳遞給另一個 grep 命令(不幸的是,因為我被困在舊版本上,所以很複雜):
search() { local file_names opt OPTARG OPTIND pattern file_names=() while getopts ":n:" opt; do case $opt in n) file_names+=( "$OPTARG" ) ;; esac done shift $((OPTIND-1)) pattern="$1" shift if (( ${#file_names[@]} > 0 )); then file_names="${file_names[@]}" file_names=${file_names// /':\|'}: grep -I -r "$pattern" "$@" | grep "$file_names" else grep -I -r "$pattern" "$@" fi }
我定義了另一個呼叫這個函式的函式:
search-some-set-of-files() { local file_names directories file_names=( "-n page1.cshtml" "-n page2.cshtml" "-n page3.cshtml" ) directories=( "/c/code/website/" "/c/stuff/something/whatever/" ) search "${file_names[@]}" "$@" "${directories[@]}" }
從命令行,我這樣呼叫這個函式:
search-some-set-of-files SomeTextIWantToSearchFor
由於某種原因,結果包括目標目錄中的每個文件。即,grep 不會根據我指定的文件名過濾結果。
如果我更改
search-some-set-of-files
函式的最後一行來回顯命令,我會得到:$ search-some-set-of-files SomeTextIWantToSearchFor search -n .cs -n .cshtml -n .html SomeTextIWantToSearchFor /c/code/website/ /c/stuff/something/whatever/
這正是我想要的。如果我將該命令(或逐字輸入)複製到命令行中,則結果應如此。
如果我啟用調試模式 (
set -x
),我可以看到每個參數都被 shell 單獨引用:$ search-some-set-of-files SomeTextIWantToSearchFor + search-some-set-of-files SomeTextIWantToSearchFor + local file_names directories + file_names=("-n page1.cshtml" "-n page2.cshtml" "-n page3.cshtml") + directories=("/c/code/website/" "/c/stuff/something/whatever/") + search '-n page1.cshtml' '-n page2.cshtml' '-n page3.cshtml' SomeTextIWantToSearchFor /c/code/website/ /c/stuff/something/whatever/ + return + etc...
所以我認為問題在於如何將參數傳遞給
search
函式。我該如何解決?
你的問題是第二個
grep
:... | grep "$file_names"
呼叫函式時,數組中包含
-n
和文件名 (-n page1.cshtml
)之間的空格。$file_names
然後,替換:file_names=${file_names// /':\|'}:
:\|
由於前導空格,將在字元串的開頭添加一個額外的。所以,你的第二個grep
命令實際上是:... | grep ":\|page1.cshtml:\|page2.cshtml:\|page3.cshtml:"
結果,
grep
匹配所有行,因為所有結果行都將包含filename:
並且匹配:
.因此,一個簡單的解決方案是刪除空格:
file_names=( "-npage1.cshtml" "-npage2.cshtml" "-npage3.cshtml" )
然後一切都應該按預期工作。