Shell-skript venter på bakgrunnskommando

Jeg skriver et skript, men det er noe jeg trenger som jeg ikke kan finne en måte å gjøre det på …

Jeg trenger å lage en kommando i bakgrunnen «command1 &» og så et sted i skriptet må jeg vente på at den er ferdig før jeg gjør kommando2. , Jeg trenger dette:

MERK: hver kommando kjører i en bestemt katalog! På slutten av stundløkken opprettet kommandoen min 4 kataloger, hvor i hver enkelt kjører den spesifikke prosessen slik at total prosess kjører er 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  

Jeg har sett noe om en wait kommando med pid-prosessnummeret, men det fungerte ikke.

Kommentarer

  • Kontrollerer du command1? Kan du endre den slik at den returnerer PID-ene til de 4 prosessene?
  • Ja! jeg har det allerede 🙂
  • Jeg har oppdatert svaret mitt tilsvarende. Fortell meg om den samsvarer med dine forventninger.
  • Denne spørsmålet er relatert til denne: unix.stackexchange.com/questions/100801/… . Den eneste forskjellen er at du trenger å få PID fra en bakgrunnsprosess. Du kan bruke $! -variabelen for å få dette, og sende det til wait -kommandoen som jeg viste der. $! inneholder den sist bakgrunnte PID, mens $$ inneholder den siste prosesskjøringen ' s PID .
  • OK, nå gir ikke skriptet ditt mening. Det er syntaksfeil og merkelighet rundt. Kan du vise oss det faktiske skriptet? Hvorfor henter du kommandoer? Hvorfor ikke bare utføre dem?

Svar

Du kan bruke kommandoen wait PID for å vente på at en prosess skal avsluttes.

Du kan også hente PID for den siste kommandoen med $!

I saken din, noe som dette vil fungere:

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 

Etter at du har endret deg, siden du har flere PID-er og du kjenner dem, kan du gjøre det:

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 

Kommentarer

  • Etter endringen din, hvis du vet at PID er opprettet (xxxxx, yyyyy, xxyyy, yyxxx ), kan du også bruke vent, med listen over PID-er å vente på (se mann). Hvis du ikke ' ikke kjenner dem, kan du kanskje samle dem i kommando1 (hva er kommando1? Et eget skript?)
  • Sannsynligvis best for å sikre at de ' er gruppert riktig i utgangspunktet. Se svaret mitt for en ide om hvordan det kan gjøres.

Svar

Den reneste måten å gjøre dette på ville være å få din comamnd1 til å returnere PIDene til de lanserte prosessene og bruke wait på hver av dem som foreslått av @LaurentC «s svar .

En annen tilnærming vil være omtrent slik:

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

Kommentarer

  • beklager, men fungerer fortsatt ikke .. Jeg vil forbedre spørsmålet mitt igjen!

Svar

Hvis du bruker følgende metode, trenger du kanskje ikke et spesielt «vent på alle prosesser» etter while-løkken. Sløyfen venter på gjeldende command1 for å fullføre før den sykler tilbake til toppen. Vær forsiktig som med alle råd. Legg merke til at det eneste jeg gjorde var å legge til & wait $! på slutten av command1.

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

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *