Aquí es un intento que trata de evitar la muerte de un proceso después de ya ha salido, lo que reduce la posibilidad de matar a otro proceso con el mismo ID de proceso (aunque es probable que sea imposible evitar este tipo de error por completo).
run_with_timeout()
{
t=$1
shift
echo "running \"$*\" with timeout $t"
(
# first, run process in background
(exec sh -c "$*") &
pid=$!
echo $pid
# the timeout shell
(sleep $t ; echo timeout) &
waiter=$!
echo $waiter
# finally, allow process to end naturally
wait $pid
echo $?
) \
| (read pid
read waiter
if test $waiter != timeout ; then
read status
else
status=timeout
fi
# if we timed out, kill the process
if test $status = timeout ; then
kill $pid
exit 99
else
# if the program exited normally, kill the waiting shell
kill $waiter
exit $status
fi
)
}
uso como run_with_timeout 3 sleep 10000
, que se extiende sleep 10000
pero termina después de 3 segundos.
Esto es como otras respuestas que utilizan un proceso de tiempo de espera de fondo para matar el proceso secundario después de un retraso. Creo que esto es casi lo mismo que la respuesta extendida de Dan (https://stackoverflow.com/a/5161274/1351983), excepto que el shell de tiempo de espera no se eliminará si ya ha finalizado.
Después de que este programa haya finalizado, todavía habrá algunos procesos de "suspensión" persistentes en ejecución, pero deberían ser inofensivos.
Esto puede ser una solución mejor que mi otra respuesta, ya que no utiliza la función de shell no portátil read -t
y no utiliza pgrep
.
Relacionado: http://stackoverflow.com/q/601543/132382 – pilcrow