Necesito un script en bash que hace lo siguiente:

  • Se inicia un proceso en segundo plano con todos los resultados, dirigido a un archivo
  • Escribe el proceso del código de salida a un archivo
  • Devuelve el proceso del pid (de inmediato, no cuando el proceso de las salidas).
  • La secuencia de comandos debe salir

Puedo obtener el pid, pero no el código de salida:

$ executable >>$log 2>&1 &
pid=`jobs -p`

O, puedo capturar el código de salida, pero no el pid:

$ executable >>$log;
# blocked on previous line until process exits
echo $0 >>$log;

¿Cómo puedo hacer todo esto al mismo tiempo?

InformationsquelleAutor Bob B | 2012-02-13

1 Comentario

  1. 56

    El pid está en $!, no hay necesidad de ejecutar jobs. Y el estado de retorno es devuelto por wait:

    $executable >> $log 2>&1 &
    pid=$!
    wait $!
    echo $?  # return status of $executable

    EDITAR 1

    Si entiendo que el requisito adicional como se indica en un comentario, y desea que el script para volver de inmediato (sin esperar a finalizar el comando), entonces no va a ser posible tener el guión inicial de escribir el estado de salida del comando. Pero es bastante fácil a través de un intermediario escribir el estado de salida tan pronto como el niño acabados. Algo así como:

    sh -c "$executable"' & echo pid=$! > pidfile; wait $!; echo $? > exit-status' &

    debería funcionar.

    EDITAR 2

    Como se señaló en los comentarios, que solución tiene una condición de carrera: el script principal termina antes de la pidfile está escrito. El OP resuelve este problema haciendo un sondeo de el sueño de bucle, que es una abominación y me temo que voy a tener problemas para dormir por la noche sabiendo que no puede haber motivado tal farsa. De la OMI, la cosa correcta a hacer es esperar hasta que el niño se hace. Ya que es inaceptable, aquí es una solución que se bloquea en una lectura hasta que el archivo pid existe en lugar de hacer el bucle de dormir:

    { sh -c "$executable > $log 2>&1 &"'
    echo $! > pidfile
    echo   # Alert parent that the pidfile has been written
    wait $!
    echo $? > exit-status
    ' & } | read
    • Muchas gracias. Que está muy cerca. Tengo miedo de que me fui de otro requisito. El guión debe terminar. Si ejecuto «esperar $pid; echo $? >>$registro» en un segundo plano script de ayuda, voy a tener un «niño» de error.
    • Si desea que el script de salida antes de que el niño termine, no es posible escribir el código de salida del niño sin necesidad de invocar una anomalía temporal de algún tipo.
    • Envuelva todo el sh -c "( $executable"' ...exit-status)' & en la sub-shell paréntesis. Que permite la subshell seguir con su vida mientras que el padre entra con todo lo que tiene que hacer. Es posible que desee agregar otro & después de la ).
    • Su propuesta sería, probablemente, para hacer más legible el código, pero sh-c cmd & tiene el mismo efecto (modulo detalles sin importancia) como ( sh-c cmd & ) &
    • Aquí están algunas notas finales. He tenido que añadir un sondeo de el sueño de bucle para asegurarse de que el archivo pid se ha generado. Cualquier vars desea utilizar en el subshell comando necesario para ser exportados, y no acaba de establecer.
    • ¿Por qué añadir un sondeo sueño bucle? Si desea esperar hasta que el niño se hace, simplemente llame a esperar!
    • No necesito esperar hasta que esté hecho, tendré que esperar hasta que se inicie. A veces, pidfile no fue creado en el tiempo.
    • He modificado la solución de modo que la parte superior del nivel de secuencia de comandos no salir hasta que el pidfile existe, pero no implica un bucle de dormir.
    • Gracias! Yo también odiaba el sueño, pero mi bash-foo no era lo suficientemente fuerte como para conseguir alrededor de él. Esta es la manera mejor.
    • Redirigir no es atómica. Creo que es posible un proceso de monitoreo a ver un vacío pidfile. Debe redireccionar a un archivo temporal y, a continuación, mover a pidfile ya que cambia de nombre son atómicas?
    • Que es un excelente punto. Personalmente, creo que tratando de hacer las cosas de manera sólida y correctamente en un script de shell como esto es peligroso, y es mejor que escribir una apropiada demonio, pero mover un tmpfile parece una solución razonable. (Excepto que ahora hay un potencial de condición de carrera con otro proceso de sobrescribir el tmpfile….que nos lleva de vuelta al primer punto)
    • Usted podría utilizar mktemp para crear el tmpfile de seguridad. Estoy realmente tratando de aprender (vs solo argumentando) así que si eso no es suficientemente bueno, por favor, hágamelo saber. También donde puedo leer acerca de lo que establece la adecuada demonios aparte de secuencias de comandos de shell?
    • El uso de mktemp no proporcionan ninguna seguridad adicional. Si un proceso escribe en un archivo temporal, luego otro de control de proceso y considera que el bloqueo no existe, entonces el primer proceso de copias de la temp archivo en el archivo de bloqueo, luego el 2º proceso de la misma. Por un demonio», me refiero sólo a un proceso que invoca el sistema de las llamadas directamente, por lo que hay menos capas. Yo no sabía que estaban siendo argumentativo, disculpas si parecía que.

Dejar respuesta

Please enter your comment!
Please enter your name here