Shell-skript väntar på bakgrundskommandot

Jag skriver ett skript, men det finns något jag behöver för att jag inte kan hitta ett sätt att göra det …

Jag måste göra ett kommando i bakgrunden ”command1 &” och sedan någonstans i skriptet måste jag vänta tills det är klart innan jag gör command2. , Jag behöver det här:

OBS: varje kommando körs i en specifik katalog! I slutet av stundslingan skapade mitt kommando1 4 kataloger, där i varje kör den specifika processen så totala processen kör är 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  

Jag har sett något om en wait -kommando med pid-processnumret, men det fungerade inte också.

Kommentarer

  • Kontrollerar du command1? Kan du ändra det så att det returnerar PID: erna för de 4 processerna?
  • Ja! jag har det redan 🙂
  • Jag har uppdaterat mitt svar därefter. Berätta för mig om den matchar dina undantag.
  • Denna fråga är relaterad till den här: unix.stackexchange.com/questions/100801/… . Den enda skillnaden är att du behöver få PID från en bakgrundsprocess. Du kan använda $! -variabeln för att få detta genom att skicka det till kommandot wait som jag visade där. $! innehåller den senast bakgrunds PID, medan $$ innehåller den sista processkörningen ' s PID .
  • Okej, nu har ditt skript ingen mening alls. Det finns syntaxfel och konstighet överallt. Kan du visa oss det faktiska skriptet? Varför köper du kommandon? Varför inte bara köra dem?

Svar

Du kan använda kommandot wait PID för att vänta på att en process ska avslutas.

Du kan också hämta PID för det senaste kommandot med $!

I ditt fall skulle något liknande fungera:

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 

Efter din redigering, eftersom du har flera PID och du känner till dem, kan du göra 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

  • Efter din redigering, om du vet att PID skapats (xxxxx, yyyyy, xxyyy, yyxxx ), kan du också använda vänta, med listan över PID att vänta på (se man). Om du ' inte känner till dem, kanske du kan samla dem i command1 (vad är command1? Ett eget skript?)
  • Förmodligen bäst för att säkerställa att de ' är grupperade korrekt i första hand. Se mitt svar för en uppfattning om hur det kan göras.

Svar

Det renaste sättet att göra detta skulle vara att din comamnd1 returnerar PID: erna för de lanserade processerna och använder wait på var och en av dem som föreslås av @LaurentC ”s svar .

Ett annat tillvägagångssätt skulle vara ungefär så här:

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

  • ledsen men fungerar fortfarande inte .. Jag kommer att förbättra min fråga än en gång!

Svara

Om du använder följande metod kanske du inte behöver ett speciellt ”vänta på alla processer” efter stundslingan. Slingan väntar på den aktuella command1 för att slutföra innan den går tillbaka till toppen. Var försiktig som med alla råd. Observera, det enda jag gjorde var att lägga till & wait $! i slutet av din command1.

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

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *