Estoy en Solaris 10 y he probado lo siguiente con ksh (88), bash (3.00) y zsh (4.2.1).
El siguiente código no produce ningún resultado:
function foo {
echo "Hello World"
}
find somedir -exec foo \;
El hallazgo coincide con varios archivos (como se muestra al reemplazar -exec ...con -print), y la función funciona perfectamente cuando se llama fuera de la findllamada.
Esto es lo que man finddice la página -exec:
-exec comando True si el comando ejecutado devuelve un
valor cero como estado de salida. El fin de
el comando debe ser puntuado por un escape
punto y coma (;). Un argumento de comando {} es
reemplazado por la ruta actual. Si el
El último argumento para -exec es {} y usted
especifique + en lugar del punto y coma (;),
el comando se invoca menos veces, con
{} reemplazado por grupos de nombres de ruta. Si
cualquier invocación del comando devuelve un
valor distinto de cero como estado de salida, buscar
devuelve un estado de salida distinto de cero.
Probablemente podría escapar haciendo algo como esto:
for f in $(find somedir); do
foo
done
Pero tengo miedo de lidiar con los problemas de separación de campos.
¿Es posible llamar a una función de shell (definida en el mismo script, no nos molestemos con problemas de alcance) desde una find ... -exec ...llamada?
Lo he probado con ambos /usr/bin/findy /bin/findy obtuve el mismo resultado.

export -f fooPATH. Alternativamente, usesh -c '...'y ambos definan Y ejecuten la función en el...bit. Puede ser útil comprender las diferencias entre funciones y scripts .Respuestas:
A
functiones local para un shell, por lo que necesitaríafind -execgenerar un shell y tener esa función definida en ese shell antes de poder usarlo. Algo como:bashpermite exportar funciones a través del entornoexport -f, por lo que puede hacer (en bash):ksh88tienetypeset -fxque exportar la función (no a través del entorno), pero eso solo puede ser usado por scripts de she-bang less ejecutados porksh, así que no conksh -c.Otra opción es hacer:
Es decir, use
typeset -fpara volcar la definición de lafoofunción dentro del script en línea. Tenga en cuenta que sifoousa otras funciones, también deberá volcarlas.fuente
kshobashen el-execcomando? Entiendo la primera, pero no la segunda ocurrencia.bash -c 'some-code' a b c,$0isa,$1isb..., así que si quieres$@serlo,a, b, cdebes insertar algo antes. Debido a$0que también se usa cuando se muestran mensajes de error, es una buena idea usar el nombre del shell, o algo que tenga sentido en ese contexto.Esto no siempre es aplicable, pero cuando lo es, es una solución simple. Establezca la
globstaropción (set -o globstaren ksh93,shopt -s globstaren bash ≥4; está activada por defecto en zsh). Luego, use**/para hacer coincidir el directorio actual y sus subdirectorios de forma recursiva.Por ejemplo, en lugar de
find . -name '*.txt' -exec somecommand {} \;, puedes ejecutarEn lugar de
find . -type d -exec somecommand {} \;, puedes correrEn lugar de
find . -newer somefile -exec somecommand {} \;, puedes correrCuando
**/no funcione para usted (porque su shell no lo tiene o porque necesita unafindopción que no tenga un análogo de shell), defina la función en elfind -execargumento .fuente
globstaropción en la versión de ksh (ksh88) que estoy usando.dtksh(ksh93 con algunas extensiones X11), pero una versión anterior y posiblemente parte de un paquete opcional donde CDE es opcional.findque excluye los archivos de puntos y no desciende en dotdirs y que clasifica la lista de archivos (los cuales pueden ser direcciones en zsh a través de calificadores de globbing). También**/*en lugar de./**/*, los nombres de archivo pueden comenzar con-.Use \ 0 como delimitador y lea los nombres de archivo en el proceso actual desde un comando generado, de esta manera:
Que está pasando aqui:
read -d ''lee hasta el siguiente \ 0 byte, por lo que no tiene que preocuparse por caracteres extraños en los nombres de archivo.-print0usa \ 0 para terminar cada nombre de archivo generado en lugar de \ n.cmd2 < <(cmd1)es lo mismo quecmd1 | cmd2excepto que cmd2 se ejecuta en el shell principal y no en un subshell./dev/nullpara garantizar que no se lea accidentalmente desde la tubería.$filenamese cita para que el shell no intente dividir un nombre de archivo que contiene espacios en blanco.Ahora,
read -dy<(...)están en zsh, bash y ksh 93u, pero no estoy seguro de las versiones anteriores de ksh.fuente
si desea un proceso secundario, generado a partir de su script, para usar una función de shell predefinida, debe exportarlo con
export -f <function>NOTA:
export -fes bash específicoya que solo un shell puede ejecutar funciones de shell :
EDITAR: esencialmente su script debería parecerse a esto:
fuente
export -fes un error de sintaxiskshe imprime la definición de la función en la pantallazsh. En totalksh,zshybash, no resuelve el problema.find / -exec /bin/bash -c 'function' \;bash. ¡Gracias!{}en el código de shell! Eso significa que el nombre del archivo se interpreta como código shell también lo es muy peligroso