Skrypt powłoki czeka na polecenie w tle

Piszę skrypt, ale jest coś, czego potrzebuję, a nie mogę znaleźć sposobu, aby to zrobić …

Muszę wydać polecenie w tle „command1 &”, a następnie gdzieś w skrypcie muszę poczekać, aż zakończy się, zanim wykonam polecenie 2. Zasadniczo , Potrzebuję tego:

UWAGA: każde polecenie działa w określonym katalogu! Na końcu pętli while moje polecenie1 utworzyło 4 katalogi, w których w każdym uruchamiany jest określony proces, więc całkowity proces uruchomione są 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  

Widziałem coś o wait z numerem procesu pid, ale to też nie zadziałało.

Komentarze

  • Czy kontrolujesz command1? Czy możesz go zmodyfikować, aby zwracał identyfikatory PID 4 procesów?
  • Tak! już to mam 🙂
  • Odpowiednio zaktualizowałem swoją odpowiedź. Powiedz mi, czy pasuje do Twoich oczekiwań.
  • Ten Q jest powiązany z tym: unix.stackexchange.com/questions/100801/… . Jedyną różnicą jest to, że musisz pobrać PID z procesu w tle. Aby to uzyskać, możesz użyć zmiennej $!, przekazując ją do polecenia wait, jak tam pokazałem. $! zawiera ostatni ustawiony w tle PID, a $$ zawiera ostatni uruchomiony proces ' s PID .
  • OK, teraz twój skrypt nie ma żadnego sensu. Dookoła są błędy składniowe i dziwactwa. Czy możesz nam pokazać rzeczywisty skrypt? Dlaczego pozyskujesz polecenia? Dlaczego ich po prostu nie wykonać?

Odpowiedz

Możesz użyć polecenia wait PID aby poczekać na zakończenie procesu.

Możesz także pobrać PID ostatniego polecenia za pomocą $!

W w Twoim przypadku coś takiego mogłoby zadziałać:

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 

Po edycji, ponieważ masz wiele identyfikatorów PID i znasz je, możesz to zrobić:

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 

Komentarze

  • Po dokonaniu edycji, jeśli znasz utworzony identyfikator PID (xxxxx, yyyyy, xxyyy, yyxxx ), możesz również użyć wait, z listą PID-ów, na które trzeba czekać (zobacz man). Jeśli nie znasz ich ', może możesz zebrać je w polecenie1 (co to jest polecenie1? Własny skrypt?)
  • Prawdopodobnie najlepiej jest upewnić się, że ' ponownie zgrupowano w pierwszej kolejności. Zobacz moją odpowiedź, aby dowiedzieć się, jak to zrobić.

Odpowiedź

Najczystszy sposób na zrobienie tego byłoby, gdyby Twój comamnd1 zwracał PID uruchomionych procesów i używając wait na każdym z nich, zgodnie z sugestią @LaurentC „s odpowiedź .

Innym podejściem byłoby coś takiego:

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

Komentarze

  • przepraszam, ale nadal nie działa .. Jeszcze raz poprawię swoje pytanie!

Odpowiedź

Jeśli użyjesz poniższej metody, możesz nie potrzebować specjalnego „oczekiwania na wszystkie procesy” po pętli while. Pętla będzie czekać na bieżące command1, aby zakończyć, zanim wróci do początku. Zachowaj ostrożność, tak jak w przypadku każdej porady. Uwaga, jedyną rzeczą, jaką zrobiłem, było dodanie & wait $! na końcu command1.

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

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *