Uruchom proces w tle i sprawdź, kiedy się kończy

Jak mogę uruchomić proces w tle i sprawdzić, kiedy kończy się w skrypcie bash? Mój pomysł to taki skrypt:

launch backgroundprocess & while [ Process is running ];do echo "PROCESS IS RUNNING\r" done; echo "PROCESS TERMINATED" 

Odpowiedź

Kluczem jest polecenie „czekaj”:

#!/bin/bash /my/process & /another/process & wait echo "All processes done!" 

Komentarze

  • Zaleta: NIE obciąża procesora czas z nieskończoną pętlą działającą przez cały czas ….;)
  • Wadą tego jest to, że nie możesz ' nic robić podczas czekania , na przykład wskazując postęp użytkownikowi. Tylko cuonglm ' rozwiązanie pozwala to zrobić.
  • @Mark Booth Możesz to zrobić wskazują postęp w trzecim asynchronicznym zadaniu. np .: cmd1 & p=$!; cmd2 & q=$!; while sleep 1; do echo still running ; done& wait $p $q; kill $!;

Odpowiedź

Z wait możesz uzyskać wymaganą szczegółowość:

sleep 1 & PID1=$! sleep 2 & PID2=$! wait $PID1 echo "PID1 has ended." wait echo "All background processes have exited." 

Odpowiedź

Oto jeden ze sposobów, aby to zrobić:

launch backgroundprocess & PROC_ID=$! while kill -0 "$PROC_ID" >/dev/null 2>&1; do echo "PROCESS IS RUNNING" done echo "PROCESS TERMINATED" exit 0 

Komentarze

  • Dziękujemy, jest to zdecydowanie jedyna odpowiedź, która daje odpowiedź na moją interpretację pierwotnego pytania (i powód, dla którego w końcu spojrzałem na to pytanie)
  • @cuonglm, Co to jest wiele procesów? Prawdopodobnie wait jest do tego bardziej odpowiedni?
  • @cuonglm co robi opcja -0 zabicia polecenia
  • @k_vishwanath informuje, czy proces nadal działa, czy nie.

Odpowiedz

Możesz uruchomić swój proces z nohup i napisać skrypt powłoki, aby czytać nohup.out, którego nohup używa do logowania.

 nohup command & 

Komentarze

  • (1) Na ryzyko rozszczepienia włosów, nohup nie ' nie zapisuje niczego na nohup.out; po prostu tworzy plik i przekierowuje do niego dane wyjściowe polecenia. (2) Jeśli polecenie nie ' nie wygeneruje żadnych danych wyjściowych, nic nie zostanie zapisane w nohup.out, a ten pomysł donikąd nie idzie. (3) Nawet jeśli command zapisuje dane wyjściowe, jak możesz stwierdzić, kiedy się kończy, monitorując to wyjście?
  • @ G- Człowieku, może sprawdzając wyjście lsof, aby zobaczyć, czy nohup nadal używa nohup.out, ale zgadzam się, że jest to bardzo skomplikowana metoda.
  • (4) Zanim command zacznie działać, nohup zniknął. (1) Tak, powtarzam numer, ponieważ powtarzam to, co powiedziałem dwa lata temu: nohup nie zapisuje niczego w nohup.out. (5) Tak, możesz napisać skrypt powłoki, aby zapętlić i uruchomić lsof, aby sprawdzić, czy nohup.out jest nadal otwarty. Ale to byłaby inna odpowiedź. (6) Nawet gdybyś to zrobił, byłoby to zawodne. A jeśli inny proces otworzył plik nohup.out? Naprawdę chciałbyś sprawdzić, czy ten konkretny proces był nohup.out otwarty. (7) Ale jeśli zamierzasz to zrobić, dlaczego nie sprawdzić, czy proces jest uruchomiony?

Odpowiedź

wait działa tylko dla procesu potomnego uruchomionego w tej samej powłoce; w końcu jest to funkcja powłoki.

W przypadku dowolnego procesu w tle musisz pracować z PID. Nikt tu nie wspomina, to recykling PID jądra. Nowoczesne systemy linux mogą ponownie używać PID często w zależności od obciążenia. Do niezawodnej identyfikacji procesu potrzebujesz czegoś więcej niż tylko PID. Jednym prostym podejściem jest oszczędność czasu kiedy proces się rozpoczął i regularnie porównuj go z bieżącą godziną rozpoczęcia procesu. Jeśli PID zostanie poddany recyklingowi, jego czas rozpoczęcia nie będzie taki sam.

Czas rozpoczęcia procesu jest podawany w polu 22 w / proc / [pid] / stat . Czas jest mierzony w jiffach (maksymalnie 10 ms), co zapewnia wystarczającą ilość precyzja wykrywania recyklingu identyfikatorów procesu.

PID=<process ID> START_TIME=$(cut -d " " -f 22 /proc/$PID/stat) while [ "$(cut -d " " -f 22 /proc/$PID/stat 2>/dev/null)" = "$START_TIME" ]; do echo "PROCESS IS RUNNING" sleep 1 done 

Dodaj komentarz

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