Andreas Veithen señala que si no necesita regresar de la llamada (como en el ejemplo del OP), simplemente llamar a través del exec
comando es suficiente ( respuesta de @Stuart P. Bentley ). De lo contrario, el "tradicional" trap 'kill $CHILDPID' TERM
(la respuesta de @ cuonglm) es un comienzo, pero la wait
llamada en realidad regresa después de que se ejecuta el controlador de trampa, que puede ser aún antes de que el proceso secundario salga. Por lo tanto, wait
se recomienda una llamada "extra" a ( respuesta de @ user1463361 ).
Si bien esto es una mejora, todavía tiene una condición de carrera, lo que significa que el proceso nunca puede salir (a menos que el señalizador vuelva a intentar enviar la señal TERM). La ventana de vulnerabilidad es entre registrar el controlador de trampa y registrar el PID del niño.
Lo siguiente elimina esa vulnerabilidad (empaquetada en funciones para su reutilización).
prep_term()
{
unset term_child_pid
unset term_kill_needed
trap 'handle_term' TERM INT
}
handle_term()
{
if [ "${term_child_pid}" ]; then
kill -TERM "${term_child_pid}" 2>/dev/null
else
term_kill_needed="yes"
fi
}
wait_term()
{
term_child_pid=$!
if [ "${term_kill_needed}" ]; then
kill -TERM "${term_child_pid}" 2>/dev/null
fi
wait ${term_child_pid}
trap - TERM INT
wait ${term_child_pid}
}
# EXAMPLE USAGE
prep_term
/bin/something &
wait_term