Contexto:
Los usuarios me proporcionan sus scripts personalizados para ejecutar. Estos scripts pueden ser de cualquier tipo, como scripts para iniciar múltiples programas GUI, servicios de back-end. No tengo control sobre cómo se escriben los guiones. Estos scripts pueden ser de tipo de bloqueo, es decir, la ejecución espera hasta que todos los procesos secundarios (programas que se ejecutan secuencialmente) salen
#exaple of blocking script
echo "START"
first_program
second_program
echo "DONE"
o tipo no bloqueante, es decir, aquellos que bifurcan el proceso secundario en segundo plano y salen como
#example of non-blocking script
echo "START"
first_program &
second_program &
echo "DONE"
¿Qué estoy tratando de lograr?
Los scripts proporcionados por el usuario pueden ser de cualquiera de los dos tipos anteriores o una combinación de ambos. Mi trabajo es ejecutar el script y esperar hasta que todos los procesos iniciados por él salgan y luego apague el nodo. Si es de tipo de bloqueo, el caso es simple, es decir, obtenga el PID del proceso de ejecución del script y espere hasta que ps -ef | grep -ef PID no tenga más entradas. Los scripts sin bloqueo son los que me están dando problemas
¿Hay alguna manera de obtener una lista de PID de todos los procesos secundarios generados por la ejecución de un script? Cualquier sugerencia o sugerencia será muy apreciada
pid$(foo.sh; echo $!)
que le dará el PIDfoo.sh
para que luego pueda usarps --ppid
. ¿Eso funcionará?grep
, solops –udummy_user
. Además, observe los grupos de procesos.ps
sin ningún argumento (debe ser solobash
yps
al principio). Comience su secuencia de comandos allí. Después de que termine, espere hasta queps | wc -l
alcance el valor esperado.Respuestas:
Para responder su pregunta directamente, el comando
le da la lista de todos los procesos secundarios.
Alternativa # 1
Pero en su caso, podría ser más fácil usar el comando
wait
sin ningún parámetro:Esto esperará hasta que TODOS los procesos secundarios hayan terminado.
Alternativa # 2
Otra alternativa es usar
$!
para obtener el PID del último programa y tal vez acumular en una variable, de esta manera:y luego use wait with that (esto es en caso de que solo quiera esperar un subconjunto de sus procesos secundarios):
Alternativa # 3
O, si desea esperar solo hasta que CUALQUIER proceso haya terminado, puede usar
Información adicional
Si desea un sigterm en su script bash para cerrar sus procesos secundarios también, necesitará propagar la señal con algo como esto (ponga esto en algún lugar en la parte superior, antes de comenzar cualquier proceso):
fuente
Gracias a todos por sus respuestas. Tengo la solución en stackoverflow
Puede usar esperar para esperar a que se completen todos los procesos en segundo plano iniciados por userscript. Dado que wait solo funciona en los elementos secundarios del shell actual, deberá obtener su script en lugar de ejecutarlo como un proceso separado.
(fuente script de usuario; espera)
Obtener el script en una subshell explícita debería simular iniciar un nuevo proceso lo suficientemente cerca. Si no es así, también puede poner en segundo plano la subshell, lo que obliga a iniciar un nuevo proceso y luego esperar a que se complete.
(fuente usercript; esperar) y esperar
Aquí está el enlace para la respuesta original de @chepner: /programming/18663196/how-to-get-list-of-all-child-process-spawned-by-a-script/18663969?noredirect = 1 # 18663969
fuente
wait
comando luego esperará a los hijos de usercript pero no a sus nietos.