Shell script espera pelo comando background

12

Eu estou escrevendo um script, mas há algo que eu preciso que não consigo encontrar uma maneira de fazer isso ...

Eu preciso fazer um comando em segundo plano "command1 &" e, em seguida, em algum lugar no script, preciso esperar que ele termine antes de fazer o comando2. Basicamente, eu preciso disso:

NOTA: cada comando é executado em um diretório específico! no final do loop while, meu comando1 criou 4 diretórios, onde em cada um deles é executado o processo específico, de modo que o total de processos em execução seja 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 comando wait com o número do processo pid, mas isso também não funcionou.

    
por Joao Macau 10.04.2014 / 16:27

3 respostas

21

Você pode usar o comando wait PID para aguardar o término de um processo.

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

No seu caso, algo assim 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 a sua edição, como você tem vários PIDs e você 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
    
por 10.04.2014 / 16:32
4

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

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
    
por 10.04.2014 / 17:32
0

Se você usar o método a seguir, talvez não seja necessário um "wait for all process" especial após o loop while. O loop esperará que o atual command1 seja concluído antes de retornar ao início. Por favor, tenha cuidado, como com qualquer conselho. Observe que a única coisa que fiz foi adicionar & wait $! ao final de seu command1 .

a=1
while [$a -lt 4 ]
     . command1  & wait $!
   #Generates 1 Process  
     a= 'export $a +1'
done
    
por 12.03.2016 / 00:38