Bash
find -exec 不在 bash 腳本中工作,但在終端中工作
我正在嘗試編寫一些 bash 腳本來替換我經常使用的命令。這是我文件中的程式碼
test.sh
#!/bin/bash echo -e "\n" i=0 args[i++]=$0 for arg in $@ ; do args[i++]=$arg done where="." what="-type f" gcase= str= while getopts "d:f:F:ih" opt ; do case $opt in h) echo -e "This is the help of this search function." echo -e "\t $0 [-d <dir>] [-f|-F <pattern>] [-i] string" echo -e "This will output the result of" echo -e "\t find dir -[i]name pattern -exec grep --color -Hn[i] string {} \;" echo -e "Default is" echo -e "\t find . -type f -exec grep --color -Hn string {} \;\n" exit 0 ;; d) OPTIND=$(($OPTIND-1)) where= tmp=${args[$OPTIND]} while [[ $OPTIND -lt $# ]] && [[ "${tmp:0:1}" != "-" ]] ; do where="$where"" $tmp" OPTIND=$(($OPTIND+1)) tmp=${args[$OPTIND]} done ;; F) what="-iname " what="$what""\"$OPTARG\"" ;; f) what="-name " what="$what""\"$OPTARG\"" ;; i) gcase="-i" ;; \?) echo "Invalide option, use option -h for help." >&2 exit 0 ;; esac done str=${args[$OPTIND]} command="find $where $what -exec grep --color -Hn $gcase \"$str\" {} \;" echo "$command" $command
現在,從我的終端,我做到了
./test.sh -d auto-avoid -F "TEST*" "main"
,我得到了find auto-avoid -iname "TEST*" -exec grep --color -Hn "main" {} \; find: missing argument to `-exec'
(
auto-avoid
是一個包含我為好玩而編寫的小型 c++ 程序的目錄。)然後,在我的終端中,我複制粘貼命令
find auto-avoid -iname "TEST*" -exec grep --color -Hn "main" {} \;
並得到auto-avoid/test.cpp:26:int main(int argc, char **argv)
這是預期的結果。
問題是:我錯過了什麼?
現在我把它寫成一個獨立的腳本來測試它,但目標是把它作為我的
.bash_aliases
.我發現了一些類似的主題,但沒有什麼可以幫助我。如果您發現這是一個重複的問題,我將很樂意採取解決方案。
我很確定有些人會告訴我使用
grep -r
,但我至少想了解為什麼我的腳本不起作用。這是一個最小的“不”工作範例,我稍後會排除一些目錄find
。
用於
set -x
查看 shell 真正嘗試執行的內容:$ command='find foo -iname "TEST*" -exec grep --color -F -Hn "main" {} \;' $ echo "$command" find foo -iname TEST* -exec grep --color -F -Hn main {} \; $ set -x $ $command + find foo -iname 'TEST*' -exec grep --color -F -Hn main '{}' '\;' find: missing argument to `-exec'
請注意
'\;'
: 您給出find
的是文字反斜杠,這不是它所期望的。雙引號完成與反斜杠相同的功能,轉義分號以便將其視為字元,而不是命令分隔符。
這些應該是等效的:
$ foo="something ;" $ foo=something\ \;
另外,請注意,執行命令行
$command
有點麻煩:如果您在傳遞給結果命令的任何參數中都有空格(例如,在您擁有的路徑名中$where
),它們將被拆分。Shell 數組提供了一種更強大的方法來做到這一點。