Contexto:
Os usuários me fornecem seus scripts personalizados para execução. Esses scripts podem ser de qualquer tipo, como scripts para iniciar vários programas GUI, serviços de back-end. 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 não bloqueador, ou seja, aqueles que bifurcam o processo filho em segundo plano e saem 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 misturar os dois. Meu trabalho é executar o script e aguardar até que todos os processos iniciados por ele saiam e, em seguida, encerre o nó. Se for do tipo de bloqueio, case é muito simples, ou seja, obtenha o PID do processo de execução do script e aguarde até que o ps -ef | grep -ef PID não tenha mais entradas. Scripts sem bloqueio são os que me dão problemas
Existe uma maneira de obter uma lista de PIDs de todo o processo filho gerado pela execução de um script? Quaisquer sugestões ou sugestões serão muito apreciadas
pid$(foo.sh; echo $!)
que fornecerá o PIDfoo.sh
para que você possa usá-lops --ppid
. Isso vai funcionar?grep
, apenasps –udummy_user
. Além disso, observe os grupos de processos.ps
sem argumentos (deve ser apenasbash
eps
no início). Inicie seu script lá. Depois de concluído, aguarde atéps | wc -l
atingir o valor esperado.Respostas:
Para responder sua pergunta diretamente, o comando
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:Isso aguardará até que TODOS os processos filhos sejam concluídos.
Alternativa # 2
Outra alternativa é usar
$!
para obter o PID do último programa e talvez se acumular em uma variável, assim:e use wait com isso (caso você deseje apenas esperar por um subconjunto de seus processos filhos):
Alternativa # 3
OU, se você quiser esperar apenas até que QUALQUER processo termine, poderá usar
Informações sobre bônus
Se você deseja que um sigterm em seu script bash feche também os processos filhos, será necessário propagar o sinal com algo assim (coloque-o em algum lugar no topo, antes de iniciar qualquer processo):
fonte
Obrigado pessoal por suas respostas .. Eu tenho a solução em stackoverflow
Você pode esperar para aguardar a conclusão de todos os processos em segundo plano iniciados pelo userscript. Como a espera funciona apenas em filhos do shell atual, você precisará originar o script deles em vez de executá-lo como um processo separado.
(fonte userscript; aguarde)
A terceirização do script em um subshell explícito deve simular o início de um novo processo de maneira suficientemente próxima. Caso contrário, você também pode colocar em segundo plano o subshell, o que força um novo processo a ser iniciado e aguarde a conclusão.
(fonte userscript; aguarde) e aguarde
Aqui está o link para a resposta original de @chepner: /programming/18663196/how-to-get-list-of-all-child-process-spawned-by-a-script/18663969?noredirect = 1 # 18663969
fonte
wait
comando aguardará os filhos do script de usuário, mas não os netos.