Digamos que tengo un script como el siguiente
#!/usr/bin/env zsh
./subscript.sh &
# do stuff
...
# do more stuff
Me gustaría que el proceso en ejecución subscript.sh
(y cualquier proceso iniciado por él) finalice por completo cuando:
- El script anterior sale
- El script anterior se elimina por cualquier motivo.
¿Cómo puedo hacer cumplir lo anterior? ¿El shell se encarga de esto automáticamente?
Respuesta1
El shell definitivamente no eliminará espontáneamente sus subprocesos; después de todo, se supone que un trabajo en segundo plano se ejecuta en segundo plano y no se preocupa por la vida de su padre. (En algunas circunstancias, un shell interactivo eliminará sus subprocesos cuando salga, lo cual no siempre es deseable, por lo tantonohup
.)
Puede hacer que el script de shell elimine sus trabajos en segundo plano cuando salga o lo elimine una señal captable. Registre los ID de proceso de los trabajos y elimínelos desde una trampa. Tenga en cuenta que esto solo elimina los trabajos (como en el proceso original que se inició en segundo plano), no sus subprocesos.
jobs=()
trap '((#jobs == 0)) || kill $jobs' EXIT HUP TERM INT
…
subscript1 & jobs+=($!)
subscript2 & jobs+=($!)
…
Si desea asegurarse de eliminar todos los procesos y sus subprocesos, es necesario realizar más planificación. Un método es hacer arreglos para que todos los procesos tengan un archivo único abierto. Para eliminarlos a todos, elimine todos los procesos que tengan este archivo abierto. Un subproceso puede escapar cerrando el archivo.
#!/bin/sh
lock_file=$(mktemp)
exec 3<"$lock_file"
your_script
status=$?
exec 3<&-
fuser -k "$lock_file"
exit $status
Respuesta2
Podría capturar EXIT y enviar una señal al grupo de procesos del script.
en linux
trap 'kill -SIGTERM 0' EXIT
en FreeBSD
trap 'kill -15 -$$' EXIT
SIGKILL
es la única señal de que esto no funcionaría ya que el guión se elimina incondicionalmente.