find -exec 不在 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

答案1

使用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),它们将被分割。壳阵列提供一种更强大的方法来做到这一点。

相关内容