GNU/Linux >> Tutoriales Linux >  >> Linux

Bash:esperar con tiempo de espera

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


Linux
  1. Bash -c con parámetros posicionales?

  2. Matrices bash con ejemplos

  3. Declaración de Bash If-Else con ejemplos

  4. Waitpid equivalente con tiempo de espera?

  5. ¿Qué hace poll() con un tiempo de espera de 0?

Cómo escribir un script Bash con ejemplos

Tutorial de Bash HereDoc con ejemplos

Comando de espera bash

Comando de espera en Linux con ejemplos

Cómo crear documentos con scripts Bash

Sintaxis de Bash If Else con ejemplos