使用变量执行 find 命令时出错

使用变量执行 find 命令时出错

我写了一个find命令来复制一些源文件:

find ./lib ./tools -type f -regex '.*\.\(cpp\|c\|h\)$' -exec cp --parents \{\} /tmp/potato \; -print

这效果很好,但我还想添加-print可选的尾随,所以我做了这样的事情:

function deploy_source_code {
    exec_cmd="find ./lib ./tools -type f -regex '.*\.\(cpp\|c\|h\)$' -exec cp --parents \{\} ${args[destdir]} \;"
    if [ "${args[verbose]}" = "true" ]; then
        exec_cmd="${exec_cmd} -print"
    fi  
    ${exec_cmd}
}

但它恰好失败并出现错误:

find: missing argument to `-exec'

我不知道为什么它会失败,我将不胜感激任何建议。提前致谢!

答案1

使用数组并将其作为简单命令的参数执行。

deploy_source_code() {
  exec_cmd=(find ./lib ./tools -type f -regex '.*\.\(cpp\|c\|h\)$' 
    -exec cp --parents {} "${args[destdir]}" \;)
  if [ "${args[verbose]}" = "true" ]; then
    exec_cmd+=(-print)
  fi  
  "${exec_cmd[@]}"
}

或者一个字符串并将其计算为 shell 代码:

deploy_source_code() {
  exec_cmd="find ./lib ./tools -type f -regex '.*\.\(cpp\|c\|h\)$' \
    -exec cp --parents {} \"\${args[destdir]}\" \;"
  if [ "${args[verbose]}" = "true" ]; then
    exec_cmd+=" -print"
  fi  
  eval "$exec_cmd"
}

请注意,在上面的代码中,重要的是要确保${args[destdir]}在赋值时不展开,否则它的内容将被传递到eval作为 shell 代码进行计算!它可能很难eval安全地使用,我会使用数组方法,特别是考虑到您已经在使用关联数组。

在您的方法中,您在字符串上使用 split+glob 运算符来创建简单命令的参数。这不起作用,因为最后一个参数findis\;而不是 just ;(而且您还会遇到传递给 的文字引号字符的问题find)。您可以使用 split+glob 运算符:

deploy_source_code() {
  exec_cmd="find ./lib ./tools -type f -regex .*\.\(cpp\|c\|h\)$ \
    -exec cp --parents {} ${args[destdir]} ;"
  if [ "${args[verbose]}" = "true" ]; then
    exec_cmd+=" -print"
  fi
  IFS=" " # split on space
  set -f  # disable glob
  $exec_cmd # invoke the split+glob operator
}

${args[destdir]}但这意味着如果包含空格字符它将不起作用。您始终可以将这些空格替换为不太可能出现在${args[destdir]}like:或换行符中的字符。

相关内容