2011-07-18 23 views
6

Necesito tomar alguna medida basada en el valor de retorno de un proceso en segundo plano, es decir, si termina en primer lugar.Valor devuelto del proceso en segundo plano

Específicamente: en funcionamiento ideal, el servidor que ejecuto como proceso en segundo plano seguirá funcionando para siempre. En tales casos, tiene sentido mantenerlo en segundo plano, ya que quiero que mi script de shell haga otras cosas después de generar el servidor. Pero si el servidor termina anormalmente, quiero usar preferiblemente el valor de retorno de salida del servidor para decidir si matar mi script principal o no. Si eso no es posible, al menos quiero abortar el script principal en lugar de ejecutarlo con un servidor fallido.

Estoy buscando algo en la naturaleza de una devolución de llamada asincrónica para scripts de shell. Una solución es generar un proceso de monitoreo que verifique periódicamente si el servidor ha fallado o no. Preferiblemente, me gustaría hacerlo sin eso dentro del script principal de shell.

Respuesta

-2

Puede anidar el proceso de fondo dentro de un script. Por ejemplo, si el proceso que desea enviar a un segundo plano se llama foo:

#!/bin/sh 

foo 

if [ $? ] 
then 
    # do something here if process failed 
fi 

A continuación, basta con ejecutar la secuencia de comandos en el fondo en lugar de foo. puede eliminarlo si necesita cerrarlo, pero de lo contrario nunca terminará mientras foo continúe ejecutándose, y si foo muere, puede hacer lo que quiera basándose en su código de error.

2

Puede utilizar capturas de shell para invocar una función cuando un niño sale atrapando SIGCHLD. Si solo se está ejecutando un proceso en segundo plano, puede wait en el controlador de sigchld y obtener el estado allí. Si hay varios hijos en segundo plano corriendo se vuelve un poco más complejo; aquí hay un ejemplo de código (solo probado con bash):

set -m # enable job control 
prtchld() { 
    joblist=$(jobs -l | tr "\n" "^") 
    while read -a jl -d "^"; do 
    if [ ${jl[2]} == "Exit" ] ; then 
     job=${jl[1]} 
     status=${jl[3]} 
     task=${jl[*]:4} 
     break 
    fi 
    done <<< $joblist 
    wait $job 
    echo job $task exited: $status 
} 
trap prtchld SIGCHLD 

(sleep 5 ; exit 5) & 
(sleep 1 ; exit 7) & 

echo stuff is running 

wait 
0

Me gusta la primera mejor para mi propósito, supongo que en el "hacer algo aquí si el proceso falló" Puedo matar el script que llamó a este guion de envoltura para foo usando su nombre.

Creo que la primera solución funciona bien para varios niños. De todos modos, tuve que hacer esto rápidamente, así que usé un truco que funciona para mi aplicación:

Empiezo el proceso en segundo plano como de costumbre dentro de la secuencia de comandos principal, luego uso $! para obtener su pid (desde $! devuelve el último bg pid), duerma durante 2 segundos y hace una ps -e | grep pid para verificar si el proceso aún se encuentra basado en el valor de retorno de (ps -e | grep pid). Esto funciona bien para mí porque si mi proceso en segundo plano aborta, lo hace de inmediato (porque la dirección está en uso).

Cuestiones relacionadas