Eu tenho um script bash que se parece com o seguinte:
##script
#!/bin/bash
rm data*
rm logfile*
for i in {1..30}
do
## append a & if you want to run it parallel;
nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" &
done
Gostaria de criar outro loop for após o primeiro para continuar por mais 30. Por exemplo
##script
#!/bin/bash
rm data*
rm logfile*
for i in {1..30}
do
## append a & if you want to run it parallel;
nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" &
for i in {31..60}
do
## append a & if you want to run it parallel;
nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" &
done
Gostaria que o primeiro conjunto de tarefas terminasse antes de iniciar o novo conjunto. Mas por causa nohup
disso, parece que todos eles são executados simultaneamente.
Eu tenho nohup
porque eu faço login remotamente no meu servidor e inicio os trabalhos lá e depois fecho o bash. Existe uma solução alternativa?
wait
embutido.Respostas:
Você deseja usar o
wait
comando para fazer isso por você. Você pode capturar todos os IDs de processo filhos e esperar por eles especificamente, ou se eles são os únicos processos em segundo plano que seu script está criando, basta ligarwait
sem um argumento. Por exemplo:fonte
Alguns pontos:
Se seu objetivo
nohup
é impedir que uma saída remota do shell mate seus processos de trabalho, você deve usarnohup
no próprio script, não nos processos de trabalho individuais que ele cria.Conforme explicado aqui ,
nohup
apenas impede que os processos recebam o SIGHUP e interajam com o terminal, mas não interrompe o relacionamento entre o shell e seus processos filhos.Por causa do ponto acima, com ou sem
nohup
, um simpleswait
entre os doisfor
loops fará com que o segundofor
seja executado somente após a saída de todos os processos filhos iniciados pelo primeirofor
.Com um simples
wait
:Se você precisar executar o segundo
for
apenas se não houver erros no primeiro, precisará salvar cada PID de trabalhador$!
e passar todos eles parawait
:fonte
R
oucc1plus
notop
comandowait
fazbash
esperar pelos trabalhos em segundo plano que gerou a si próprio, nada mais. Pode haver alguma confusão aqui - essesfor
loops, você os salvou em um arquivo e os invocou como um script (o que eu assumi, por causa da##script
linha), ou você os está digitando manualmente no terminal?Use o
fg
builtin. Aguarda até que os processos em segundo plano sejam concluídos.Tente
help fg
para detalhes.fonte
Se você inserir algo como o seguinte segmento de código entre seus dois
for
loops, isso poderá ajudar.Obviamente, se o seu aplicativo
Rscript
tiver uma chance de não ser concluído com êxito e permanecer por aí, o segundo loop for poderá não ter a chance de ser executado. O segmento de código acima pressupõe que todos os processos com o identificadorRscript --vanilla
serão concluídos e desaparecerão corretamente. Sem saber o que seu aplicativo faz e como ele é executado, tenho que confiar nessa suposição.EDITAR
À luz dos comentários, isso melhor atenderia às suas necessidades. (inclui o código original e a lógica de verificação de conclusão)
fonte
top
mostraR
às vezes oucc1plus
.ps -ef
lista. Ou após cadanohup
comando, registre o PID em uma variável (de preferência uma matriz)echo ${!}
e verifique esse grupo de PIDs. Quando todos eles desaparecem, você pode avançar para o segundofor
ciclo