Tanto su ejemplo como la respuesta aceptada son demasiado complicados, ¿por qué no solo usa timeout
ya que eso es exactamente su caso de uso? El timeout
comando incluso tiene una opción incorporada (-k
) para enviar SIGKILL
después de enviar la señal inicial para terminar el comando (SIGTERM
por defecto) si el comando aún se está ejecutando después de enviar la señal inicial (ver man timeout
).
Si el script no requiere necesariamente wait
y reanudar el flujo de control después de esperar, es simplemente una cuestión de
timeout -k 60s 60s app1 &
timeout -k 60s 60s app2 &
# [...]
Sin embargo, si es así, es igual de fácil guardando el timeout
PID en su lugar:
pids=()
timeout -k 60s 60s app1 &
pids+=($!)
timeout -k 60s 60s app2 &
pids+=($!)
wait "${pids[@]}"
# [...]
Por ejemplo
$ cat t.sh
#!/bin/bash
echo "$(date +%H:%M:%S): start"
pids=()
timeout 10 bash -c 'sleep 5; echo "$(date +%H:%M:%S): job 1 terminated successfully"' &
pids+=($!)
timeout 2 bash -c 'sleep 5; echo "$(date +%H:%M:%S): job 2 terminated successfully"' &
pids+=($!)
wait "${pids[@]}"
echo "$(date +%H:%M:%S): done waiting. both jobs terminated on their own or via timeout; resuming script"
.
$ ./t.sh
08:59:42: start
08:59:47: job 1 terminated successfully
08:59:47: done waiting. both jobs terminated on their own or via timeout; resuming script
Escriba los PID en los archivos e inicie las aplicaciones de esta manera:
pidFile=...
( app ; rm $pidFile ; ) &
pid=$!
echo $pid > $pidFile
( sleep 60 ; if [[ -e $pidFile ]]; then killChildrenOf $pid ; fi ; ) &
killerPid=$!
wait $pid
kill $killerPid
Eso crearía otro proceso que duerme durante el tiempo de espera y mata el proceso si no se ha completado hasta el momento.
Si el proceso se completa más rápido, el archivo PID se elimina y el proceso asesino finaliza.
killChildrenOf
es un script que recupera todos los procesos y mata a todos los hijos de un determinado PID. Consulte las respuestas de esta pregunta para conocer las diferentes formas de implementar esta funcionalidad:La mejor manera de eliminar todos los procesos secundarios
Si desea salir de BASH, puede escribir PID y tiempos de espera en un directorio y observar ese directorio. Cada minuto más o menos, lea las entradas y verifique qué procesos aún están activos y si se han agotado.
EDITAR Si desea saber si el proceso ha muerto con éxito, puede utilizar kill -0 $pid
EDITAR2 O puede probar los grupos de procesos. kevinarpe dijo:Para obtener PGID para un PID (146322):
ps -fjww -p 146322 | tail -n 1 | awk '{ print $4 }'
En mi caso:145974. Entonces se puede usar PGID con una opción especial de matar para terminar todos los procesos en un grupo:kill -- -145974