Bash

find -exec 不在 bash 腳本中工作,但在終端中工作

  • February 11, 2017

我正在嘗試編寫一些 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 數組提供了一種更強大的方法來做到這一點。

引用自:https://unix.stackexchange.com/questions/343468