2011-10-21 11 views
21

Tengo un script que intenta hacer una conexión de base de datos utilizando otro programa y el tiempo de espera (2.5min) del programa es demasiado largo. Quiero agregar esta funcionalidad a la secuencia de comandos.¿Matar el proceso después de un tiempo determinado?

Si transcurren más de 5 segundos para conectarse, elimine el proceso
Else kill the sleep/kill process.

El problema que tengo es cómo informa bash cuando se mata un proceso, eso se debe a que los procesos están en el mismo shell solo en el fondo. ¿Hay una mejor manera de hacerlo o cómo puedo silenciar el shell para los comandos kill?

DB_CONNECTION_PROGRAM > $CONNECTFILE & 
pid=$! 
(sleep 5; kill $pid) & 
sleep_pid=$! 
wait $pid 

# If the DB failed to connect after 5 seconds and was killed 
status=$? #Kill returns 128+n (fatal error) 
if [ $status -gt 128 ]; then 
    no_connection="ERROR: Timeout while trying to connect to $dbserver" 
else # If it connected kill the sleep and any errors collect 
    kill $sleep_pid 
    no_connection=`sed -n '/^ERROR:/,$p' $CONNECTFILE` 
fi 
+0

Encontré viejos scripts de Bash y son muy similares a tu.Estaba usando el bit-bucket (*/dev/null *) y * kill -9 * de forma mucho más liberal y no creo que hubiera mucho problema con * kill * mostrando un mensaje no deseado: curiosamente, ese código mío sigue siendo en uso, años después, ¡en mi símbolo del sistema! (Si hubiera problemas de visualización, lo vería en mi mensaje, creo). Ha pasado mucho tiempo sin tocarlo, pero parece que (todavía) funciona bien. – TacticalCoder

+0

Recopilé la carne de mi script de shell Bash como respuesta. Espero eso ayude. – TacticalCoder

+0

Eche un vistazo a esto: http://redflo.de/tiki-index.php?page=Bash+script+with+timeout+function –

Respuesta

9

No sé si es idéntica pero lo hice arreglar un problema similar hace algunos años. Sin embargo, soy un programador, no un administrador de sistemas tipo Unix, así que tome lo siguiente con un grano de sal porque mi Bash-fu puede no ser tan fuerte ...

Básicamente hice tenedor, tenedor y tenedor:)

Fuera de la memoria Después de fundar volver a mi antiguo código (que sorprendentemente todavía uso diario), porque mi memoria no era lo suficientemente bueno, en Bash funcionó un poco como esto:

commandThatMayHang.sh 2 > /dev/null 2>&1 & (notice that last '&', we're forking) 
MAYBE_HUNG_PID=$! 
sleepAndMaybeKill.sh $MAYBE_HUNG_PID 2 > /dev/null 2>&1 & (we're forking again) 
SLEEP_AND_MAYBE_KILL_PID=$! 
wait $MAYBE_HUNG_PID > /dev/null 2>&1 
if [ $? -eq 0 ] 
    # commandThatMayHand.sh did not hang, fine, no need to monitor it anymore 
    kill -9 $SLEEP_AND_MAYBE_KILL 2> /dev/null 2>&1 
fi 

donde sleepAndMaybeKill .sh duerme la cantidad de tiempo que desee y luego mata commandThatMayHand.sh.

Así que, básicamente, los dos escenarios son:

  1. sus salidas de comando fina (antes de sus 5 segundos de tiempo de espera o lo que sea) y por lo que el esperan parada tan pronto como su orden acaba bien (y mata al " asesino" porque no se necesita más

  2. el comando se bloquea, el asesino acaba matando el comando

En cualquier caso, se garantiza que tendrá éxito tan pronto como finalice el comando o que falle después del tiempo de espera.

0

¿Quiere decir que no desea que se imprima el mensaje de error si el proceso aún no se está ejecutando? Entonces podría redirigir stderr: kill $pid 2>/dev/null.

También puede comprobar si el proceso todavía está en ejecución:

if ps -p $pid >/dev/null; then kill $pid; fi 
+0

Quiero que se ejecute y si tarda más de 5 segundos en conectarse (cambiar estado) Quiero que se mate el PID. De lo contrario, quiero detener el sueño y matar al PID incluso al correr y matar al PID ya que fue exitoso. – LF4

87

Hay un GNU coreutils utilidad llamada de tiempo de espera: http://www.gnu.org/s/coreutils/manual/html_node/timeout-invocation.html

Si lo tienes en su plataforma, que podría hacer:

timeout 5 CONNECT_TO_DB 
if [ $? -eq 124 ]; then 
    # Timeout occurred 
else 
    # No hang 
fi 
+5

En Mac: prepare coreutils de instalación. Ahora el comando es gtimeout. –

+1

Esta debería ser la respuesta aceptada. –

Cuestiones relacionadas