Shell script așteaptă comanda de fundal

Scriu un script, dar este ceva de care am nevoie și nu pot găsi o modalitate de a o face …

Trebuie să fac o comandă în fundal „command1 &” și apoi undeva în script trebuie să aștept să se termine înainte să fac comanda2. Practic , Am nevoie de acest lucru:

NOTĂ: fiecare comandă rulează într-un director specific! La sfârșitul buclei while comanda mea1 a creat 4 directoare, unde în fiecare rulează procesul specific, deci totalul procesului running are 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  

Am „văzut ceva despre un wait cu numărul procesului pid, dar și asta nu a funcționat.

Comentarii

  • Controlați command1? Îl puteți modifica astfel încât să returneze PID-urile celor 4 procese?
  • Da! Am deja asta 🙂
  • Mi-am actualizat răspunsul în consecință. Spune-mi dacă se potrivește cu așteptările tale.
  • Acest Q este legat de acesta: unix.stackexchange.com/questions/100801/… . Singura diferență este că trebuie să obțineți PID dintr-un proces de fundal. Puteți utiliza variabila $! pentru a obține acest lucru, trecând-o la comanda wait așa cum am arătat acolo. $! conține ultimul PID cu fundal, în timp ce $$ conține ultimul proces rulat ' s PID .
  • OK, acum scriptul dvs. nu are deloc sens. Există erori de sintaxă și ciudățenii în jur. Ne-ai putea arăta scriptul actual ? De ce achiziționați comenzi? De ce nu le executăm?

Răspuns

Puteți utiliza comanda wait PID pentru a aștepta finalizarea unui proces.

De asemenea, puteți prelua PID-ul ultimei comenzi cu $!

În cazul dvs., așa ceva ar funcționa:

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 

După editarea dvs., deoarece aveți mai multe PID-uri și le cunoașteți, puteți face acest lucru:

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 

Comentarii

  • După editarea dvs., dacă cunoașteți PID-ul creat (xxxxx, aaaaa, xxyyy, yyxxx ), puteți utiliza, de asemenea, așteptați, cu lista PID-urilor de așteptat (vezi om). Dacă ' le cunoașteți, poate le puteți aduna în comanda1 (ce este comanda1? Un script propriu?)
  • Probabil cel mai bine pentru a vă asigura că ' a fost grupat corect în primul rând. Vedeți răspunsul meu pentru o idee despre cum ar putea fi realizat.

Răspuns

Cel mai curat mod de a face acest lucru ar fi ca comamnd1 să vă returneze PID-urile proceselor lansate și să utilizați wait pe fiecare dintre ele, așa cum sugerează @LaurentC „s answer .

O altă abordare ar fi ceva de genul acesta:

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

Comentarii

  • îmi pare rău, dar încă nu funcționează .. Îmi voi îmbunătăți încă o dată întrebarea!

Răspunde

Dacă utilizați următoarea metodă, este posibil să nu aveți nevoie de o „așteptare specială pentru toate procesele” după bucla while. Bucla va aștepta actualul command1 pentru a finaliza înainte de a reveni în sus. Vă rugăm să aveți grijă ca în cazul oricărui sfat. Observați, singurul lucru pe care l-am făcut a fost să adaug & wait $! la sfârșitul command1.

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

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *