Como obter lista de todos os processos filhos gerados por um script

8

Contexto:

Os usuários me fornecem seus scripts personalizados para serem executados. Esses scripts podem ser de qualquer tipo, como scripts, para iniciar vários programas GUI, serviços de back-end. Eu não tenho controle sobre como os scripts são escritos. Esses scripts podem ser do tipo de bloqueio, ou seja, a execução aguarda até que todos os processos filhos (programas executados sequencialmente) saiam

#exaple of blocking script
echo "START"
first_program 
second_program 
echo "DONE"

ou tipo sem bloqueio, ou seja, aqueles que bloqueiam o processo filho no plano de fundo e encerram algo como

#example of non-blocking script
echo "START"
first_program &
second_program &
echo "DONE"

O que estou tentando alcançar?

Os scripts fornecidos pelo usuário podem ser de qualquer um dos dois tipos acima ou uma combinação de ambos. Meu trabalho é executar o script e esperar até que todos os processos iniciados por ele saiam e, em seguida, desliguem o nó. Se for do tipo blocking, case é simples, ou seja, pegue o PID do processo de execução do script e espere até que ps -ef | grep -ef PID não tenha mais entradas. Scripts sem bloqueio são os que me causam problemas

Existe uma maneira de obter uma lista de PIDs de todo o processo filho gerado pela execução de um script? Quaisquer ponteiros ou dicas serão muito apreciados

    
por irraju 06.09.2013 / 19:15

2 respostas

1

Obrigado pessoal por suas respostas .. Eu tenho a solução em stackoverflow

Você pode usar a espera para esperar que todos os processos de segundo plano iniciados pelo userscript sejam concluídos. Como a espera só funciona nos filhos do shell atual, você precisará criar o script em vez de executá-lo como um processo separado.

(fonte userscript; espera)

O fornecimento do script em um subshell explícito deve simular o início de um novo processo de perto o suficiente. Se não, você também pode colocar em segundo plano o subshell, o que força um novo processo a ser iniciado, então espere que ele seja concluído.

(fonte userscript; espera) & espera

Aqui está o link para a resposta original por @chepner: link

    
por 10.09.2013 / 07:55
5

Para responder à sua pergunta diretamente, o comando

jobs -p

fornece a lista de todos os processos filhos.

Alternativa # 1

Mas, no seu caso, pode ser mais fácil usar o comando wait sem nenhum parâmetro:

first_program &
second_program &
wait

Isso esperará até que os processos filhos ALL tenham terminado.

Alternativa # 2

Outra alternativa é usar $! para obter o PID do último programa e talvez acumular em uma variável, assim:

pids=""
first_program &
pids="$pids $!"
second_program &
pids="$pids $!"

e, em seguida, use wait with that (isto é, caso você queira apenas esperar por um subconjunto de seus processos filhos):

wait $pids

Alternativa # 3

OU, se você quiser esperar apenas até que o processo ANY termine, use

wait -n $pids

Informação do bônus

Se você quiser que um sigterm no seu script bash feche seus processos filhos também, você precisará propagar o sinal com algo parecido com isto (coloque isso em algum lugar no topo, antes de iniciar qualquer processo):

trap 'kill $(jobs -p)' SIGINT SIGTERM EXIT
    
por 02.08.2015 / 18:41