He escrito un find
comando para copiar algunos archivos fuente:
find ./lib ./tools -type f -regex '.*\.\(cpp\|c\|h\)$' -exec cp --parents \{\} /tmp/potato \; -print
Esto funciona bien, pero también quiero agregar el final -print
opcionalmente, así que hago algo como esto:
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}
}
Pero sucede que falla con un error:
find: missing argument to `-exec'
No sé por qué falla y agradecería cualquier consejo. ¡Gracias de antemano!
Respuesta1
Utilice una matriz y ejecútela como argumentos para un comando simple.
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[@]}"
}
O una cadena y evaluarla como código 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"
}
Tenga en cuenta que en el código anterior, es importante asegurarse de que ${args[destdir]}
no esté expandido en el momento de la asignación, de lo contrario, su contenido se pasaría para eval
evaluarlo como código shell. Puede ser difícil usarlo eval
de manera segura, yo optaría por el enfoque de matriz, especialmente considerando que ya estás usando matrices asociativas.
En su enfoque, estaba utilizando el operador split+glob en su cadena para crear los argumentos de un comando simple. Eso no funcionó porque el último argumento find
fue \;
en lugar de just ;
(y también tendrías problemas con las comillas literales pasadas a find
). Podrías usar el operador split+glob como:
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
}
Pero eso significa que no funcionará si ${args[destdir]}
contiene caracteres de espacio. Siempre puedes reemplazar esos espacios con un carácter que sea menos probable que aparezca en ${args[destdir]}
me gusta :
o en una nueva línea.