2010-02-18 32 views
7

Esperar no está esperando a que se detengan todos los procesos secundarios. Esta es mi guión:Hacer que el comando "Esperar" de Linux espere a TODOS los procesos secundarios

#!/bin/bash 

titlename=`echo "[email protected]"|sed 's/\..\{3\}$//'` 
screen -X title "$titlename" 

/usr/lib/process.bash -verbose [email protected] 

wait 

bash -c "mail.bash [email protected]" 
screen -X title "$titlename.Done" 

que no tienen acceso a /usr/lib/process.bash, pero es un script que cambia con frecuencia, por lo que me gustaría hacer referencia a ella ... pero en ese guión:

#!/bin/ksh 
#lots of random stuff 
/usr/lib/runall $path $auto $params > /dev/null 2>&1& 

Mi problema es que runall crea un archivo de registro ... y mail.bash se supone que me envía ese archivo de registro, pero la espera no está esperando runall para terminar, parece solo estar esperando process.bash para terminar. ¿Hay de todos modos, sin acceso a process.bash, o tratando de mantener mi propia versión actualizada de process.bash, para que la espera espere adecuadamente runall para terminar? (El archivo de registro sobrescribe la ejecución anterior, por lo que no puede limitarse a verificar la presencia del archivo de registro, ya que siempre hay una allí)

Gracias, Dan

+0

¿Nos puede proporcionar a las partes correspondientes de 'ps-ef 'después de' esperar' ha terminado? Eso debería mostrar qué procesos se están ejecutando y qué proceso es secundario de qué otro proceso ... – Heinzi

+0

Mi script y Process.bash terminan casi al instante. El único proceso restante es runall, que se ejecuta bajo PID aleatorios. – Dan

Respuesta

9
(
    . /usr/lib/process.bash -verbose [email protected] 
    wait 
) 

lugar de dejar que el sistema operativo se inicia process.bash, esto crea un subnivel, se ejecuta todos los comandos en process.bash como si se ingresaron en nuestro script de shell y espera dentro de esa subshell.

Hay algunas advertencias sobre esto, pero debería funcionar si no está haciendo algo inusual.

+0

Wow ...Entonces, ¿Runall es un proceso secundario de mi script? Esto funcionó como un hechizo (tuve que cambiar mi script a ksh para que coincida con process.bash). Ctrl + C solo detiene la espera, en lugar de runall ... Idealmente, solo podría ejecutar process.bash sin el "y", pero no puedo modificar ese código, y no quiero seguir actualizando mi código everytime process.bash cambia. Gracias. – Dan

+3

Para que Ctrl-C mate el proceso en segundo plano, use trap y kill: 'pid = $ !; trampa "kill $ pid; wait $ pid; exit 0" SIGINT SIGTERM; espera $ pid' –

4

wait sólo espera para los niños directos; si algún niño engendra a sus propios hijos, no los esperará.

+0

¿Hay alguna forma de esto alrededor? ¿Si quiero que espere a todos los niños, directa e indirectamente? – Dan

+1

La única otra forma es esperar por PID o jobspec. –

2

El problema principal es que debido a que process.bash ha salido del proceso runall quedará huérfano y será propiedad de init (PID 1). Si nos fijamos en la lista de procesos, runall ya no tendrá ninguna conexión visible con su proceso ya que el script intermedio process.bash salió. No hay forma de usar ps --ppid o algo similar para buscar este proceso de "nieta" una vez que quede huérfano.

Puede wait en un PID específico. ¿Conoce el PID del proceso runall? Si sólo hay uno de estos procesos puede probar esto, que esperar a que todos se ejecutan runall s:

wait `pidof runall` 
+0

Esto no funciona ya que el runall no es un elemento secundario del script original. – abhaga

1

Se podría recuperar el PID del proceso para el que desea que esperar

y luego pasar este PID como un argumento para el comando Espera

Cuestiones relacionadas