Lo script Shell attende il comando in background


12

Sto scrivendo una sceneggiatura, ma c'è qualcosa di cui ho bisogno che non riesco a trovare un modo per farlo ...

Ho bisogno di fare un comando in background "command1 &" e poi da qualche parte nello script devo aspettare che finisca prima di eseguire command2. Fondamentalmente, ho bisogno di questo:

NOTA: ogni comando viene eseguito in una directory specifica! alla fine del ciclo while il mio comando1 ha creato 4 directory, dove in ognuna viene eseguito il processo specifico in modo che il totale del processo in esecuzione sia 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

Ho visto qualcosa su un waitcomando con il numero di processo pid, ma anche quello non ha funzionato.


Controlli command1? Puoi modificarlo in modo che restituisca i PID dei 4 processi?
terdon

Sì! ce l'ho già :)
Joao Macau,

Ho aggiornato la mia risposta di conseguenza. Dimmi se corrisponde alle tue aspettative.
Laurent C.,

Questa Q è correlata a questa: unix.stackexchange.com/questions/100801/… . L'unica differenza è che è necessario ottenere il PID da un processo in background. È possibile utilizzare la $!variabile per ottenere questo, passandolo al waitcomando come ho mostrato lì. $!contiene l'ultimo PID in background, mentre $$contiene il PID dell'ultima esecuzione del processo.
slm

3
OK, ora la tua sceneggiatura non ha alcun senso. Ci sono errori di sintassi e stranezze tutt'intorno. Potresti mostrarci la sceneggiatura attuale ? Perché stai provando i comandi? Perché non solo eseguirli?
terdon

Risposte:


22

È possibile utilizzare il comando wait PIDper attendere la fine di un processo.

È inoltre possibile recuperare il PID dell'ultimo comando con $!

Nel tuo caso, qualcosa del genere funzionerebbe:

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

Dopo la modifica, poiché hai più PID e li conosci, puoi farlo:

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

Dopo la modifica, se si conosce il PID creato (xxxxx, yyyyy, xxyyy, yyxxx), è possibile utilizzare anche wait, con l'elenco dei PID da attendere (vedi man). Se non li conosci, forse li puoi riunire in command1 (che cos'è command1? Una tua sceneggiatura?)
Laurent C.

Probabilmente è meglio assicurarsi che siano raggruppati correttamente in primo luogo. Vedi la mia risposta per avere un'idea di come potrebbe essere fatto.
Mikeserv,

4

Il modo più pulito per farlo sarebbe ottenere il comamnd1ritorno dei PID dei processi avviati e utilizzarli waitsu ciascuno di essi, come suggerito dalla risposta di @ LaurentC .

Un altro approccio sarebbe qualcosa del genere:

## 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

scusa ma ancora non funziona .. Migliorerò ancora una volta la mia domanda!
Joao Macau,

0

Se si utilizza il metodo seguente, potrebbe non essere necessario uno speciale "attendere tutti i processi" dopo il ciclo while. Il loop attenderà il command1completamento della corrente prima di tornare all'inizio. Si prega di prestare attenzione come per qualsiasi consiglio. Nota, l'unica cosa che ho fatto è stata aggiungere & wait $!alla fine del tuo command1.

a=1
while [$a -lt 4 ]
     . command1  & wait $!
   #Generates 1 Process  
     a= `export $a +1`
done
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.