Script shell espera pelo comando de fundo

Estou escrevendo um script, mas há algo que preciso e não consigo encontrar uma maneira de fazer …

Eu preciso fazer um comando em segundo plano “command1 &” e então em algum lugar no script eu preciso esperar que ele termine antes de fazer o command2. Basicamente , Eu preciso disso:

NOTA: cada comando é executado em um diretório específico! No final do loop while meu comando1 criou 4 diretório “s, onde em cada um executa o processo específico para o total do processo em execução são 4

 a=1 while [$a -lt 4 ] . command1 #Generates 1 Process a= `export $a +1` done #Wait until the 4 process end and then run the command2 . command2  

Eu vi algo sobre um wait comando com o número do processo pid, mas isso não funcionou também.

Comentários

  • Você controla command1? Você pode modificá-lo para que retorne os PIDs dos 4 processos?
  • Sim! eu já tenho 🙂
  • Eu atualizei minha resposta de acordo. Diga-me se corresponde às suas expectativas.
  • Este Q está relacionado a este: unix.stackexchange.com/questions/100801/… . A única diferença é que você precisa obter o PID de um processo em segundo plano. Você pode usar a variável $! para obter isso, passando-o para o comando wait como mostrei lá. $! contém o último PID em segundo plano, enquanto $$ contém a última execução do processo ' s PID .
  • OK, agora o seu script não faz sentido algum. Existem erros de sintaxe e estranheza por toda parte. Você poderia nos mostrar o script real ? Por que você está fornecendo comandos? Por que não apenas executá-los?

Resposta

Você pode usar o comando wait PID para esperar que um processo termine.

Você também pode recuperar o PID do último comando com $!

Em seu caso, algo como isto funcionaria:

command1 & #run command1 in background PID=$! #catch the last PID, here from command1 command2 #run command2 while command1 is running in background wait $PID #wait for command1, in background, to end command3 #execute once command1 ended 

Após sua edição, como você tem vários PIDs e os conhece, você pode fazer isso:

command1 & #run command1 in background PID1=xxxxx PID2=yyyyy PID3=xxyyy PID4=yyxxx command2 #run command2 while command1 is running in background wait $PID1 $PID2 $PID3 $PID4 #wait for the four processes of command1, in background, to end command3 #execute once command1 ended 

Comentários

  • Após sua edição, se você souber o PID criado (xxxxx, yyyyy, xxyyy, yyxxx ), você pode usar esperar também, com a lista de PIDs a serem aguardados (veja o man). Se você não ' os conhecer, talvez possa agrupá-los em command1 (o que é command1? Um script de sua preferência?)
  • Provavelmente melhor garantir que eles ' re agrupado corretamente em primeiro lugar. Veja minha resposta para uma ideia de como isso pode ser feito.

Resposta

A maneira mais limpa de fazer isso seria ter seu comamnd1 retornando os PIDs dos processos iniciados e usando wait em cada um deles, conforme sugerido por @LaurentC “s resposta .

Outra abordagem seria algo assim:

## Create a log file logfile=$(mktemp) ## Run your command and have it print into the log file ## when it"s finsihed. command1 && echo 1 > $logfile & ## Wait for it. The [ ! -s $logfile ] is true while the file is ## empty. The -s means "check that the file is NOT empty" so ! -s ## means the opposite, check that the file IS empty. So, since ## the command above will print into the file as soon as it"s finished ## this loop will run as long as the previous command si runnning. while [ ! -s $logfile ]; do sleep 1; done ## continue command2 

Comentários

  • desculpe, mas ainda não estou funcionando .. Vou melhorar minha pergunta mais uma vez!

Resposta

Se você usar o método a seguir, pode não precisar de um “esperar por todos os processos” especial após o loop while. O loop aguardará pelo para concluir antes de voltar ao início do ciclo. Tenha cuidado como com qualquer conselho. Observe, a única coisa que fiz foi adicionar & wait $! ao final do seu command1.

a=1 while [$a -lt 4 ] . command1 & wait $! #Generates 1 Process a= `export $a +1` done 

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *