¿Es posible atrapar la salida / retorno de una función? Para un programa que podría hacer
trap -- "clean_this" EXIT
Eso ejecutaría la función. clean_this
cuando el programa sale.
Me gustaría hacer algo por el estilo al salir de una función.
function myfunc() {
echo "I'm a function"
}
myfunc &
wait $!
Ejecuto la función en un subshell, y me gustaría atrapar su salida / retorno. ¿Es eso posible?
EDITAR1
Aquí está mi propósito
Tengo un script para administrar los archivos temporales:
cat tempfiles.sh
## List of temp files
tmp_tmp_files=()
## Adds a file to the list of temp files
function tmp_add_file() {
tmp_tmp_files+=("$1")
}
## Resets the list of temp files
function tmp_reset_files() {
tmp_tmp_files=()
}
## Removes the list of temp files
function tmp_rm_all() {
rm -f "${tmp_tmp_files[@]}"
}
## Removes all temp files on exit and sigint
trap "tmp_rm_all" EXIT SIGINT
Aquí está mi guión principal:
cat mscript.sh
source tempfiles.sh
## ## Creates a temp file and writes in it
mfunc() {
local tempfile=$(mktemp)
tmp_add_file $tempfile
echo "something" >> $tempfile
echo "($BASHPID) - tempfiles: ${tmp_tmp_files[@]}"
}
## Creates a temp file in main shell
mfunc
## Creates a temp file in a subshell
(mfunc)
Llamo al guión principal:
$ bash mscript.sh
(92250) - tempfiles: /var/folders/9k/h6hn75090_n8z0kythwmwqp96_0t2m/T/tmp.oRlUxEBj
(92254) - tempfiles: /var/folders/9k/h6hn75090_n8z0kythwmwqp96_0t2m/T/tmp.oRlUxEBj /var/folders/9k/h6hn75090_n8z0kythwmwqp96_0t2m/T/tmp.s1iIvtpq
Reviso los archivos temporales:
$ cat /var/folders/9k/h6hn75090_n8z0kythwmwqp96_0t2m/T/tmp.oRlUxEBj
cat: /var/folders/9k/h6hn75090_n8z0kythwmwqp96_0t2m/T/tmp.oRlUxEBj: No such file or directory
$ cat /var/folders/9k/h6hn75090_n8z0kythwmwqp96_0t2m/T/tmp.s1iIvtpq
something
Los archivos temporales declarados en el subshell
se pierden de la lista al salir del programa. Me gustaría tenerlos eliminados idealmente al final de la función. O tengo que eliminarlos específicamente antes de abandonar la función, es fácil y me cuesta una línea más:
mfunc() {
local tempfile=$(mktemp)
tmp_add_file $tempfile1
echo "something" >> $tempfile
echo "tempfiles: ${tmp_tmp_files[@]}"
## Process things...
rm $tempfile1
}
Pero me gustaría saber si hay una manera elegante de tenerlos (los archivos temporales creados en el subshells
) eliminado automáticamente, como hago con trap
s al salir del programa.
Entonces mi pregunta es: ¿es posible hacerlo? ¿Cuáles podrían ser algunas alternativas?
myfunc
llamadaclean_this
al final. O invocarlos como{ myfunc ; clean_this ; } &
. ¿Realmente necesitas una trampa?Respuestas:
Las subshells heredan el entorno o parte de él. Parece que cuando ejecutas una función en un subshell, no necesitas exportar tus variables (compara: No es necesario exportar cuando se ejecutan funciones en subshell ). Puede haber algunos casos en los que necesite
export
Pero concentrémonos en tu ejemplo.Su enfoque es defectuoso y será difícil de mantener porque la herencia va en un sentido. Cada
(mfunc)
heredatmp_tmp_files
Y trabaja con su propia copia de la matriz. No hay forma de que pueda modificar el original.tmp_tmp_files
utilizado en el guión principal. Por lo tanto, el script principal no puede limpiar todo, simplemente no posee suficiente información.Si elige limpiar de la función subshelled, deberá prestar atención y diferenciar los archivos temporales de la función de los archivos temporales del script principal. La eliminación prematura de este último puede hacer que su script falle.
Enfoque alternativo: un directorio temporal.
En lugar de crear una matriz, cree un directorio y recuerde su ruta. Hazlo una vez en el principio y
export
si necesitas:Crea cada archivo temporal dentro del directorio temporal, como este:
Al final, elimine todo el directorio, sin importar si los archivos en particular fueron creados por el script principal o por un subshell, o incluso por algún programa externo de terceros. Puedes usar una trampa para realizar este paso. Simplemente:
fuente