我写了一个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 运算符来创建简单命令的参数。这不起作用,因为最后一个参数find
is\;
而不是 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:
或换行符中的字符。