Mam skrypt basha, który wygląda następująco:
##script #!/bin/bash rm data* rm logfile* for i in {1..30} do ## append a & if you want to run it parallel; nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" & done 
Chciałbym utworzyć kolejną pętlę for po pierwszej, aby kontynuować przez kolejne 30. Na przykład
##script #!/bin/bash rm data* rm logfile* for i in {1..30} do ## append a & if you want to run it parallel; nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" & for i in {31..60} do ## append a & if you want to run it parallel; nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" & done 
 Chciałbym pierwszy zestaw zadań do zakończenia przed rozpoczęciem nowego zestawu. Ale z powodu nohup wydaje się, że wszystkie działają jednocześnie. 
 Mam nohup, ponieważ zdalnie loguję się do mojego serwera i rozpoczynam tam zadania, a następnie zamykam bash. Czy jest jakieś alternatywne rozwiązanie? 
Komentarze
Odpowiedź
 Będziesz chciał użyć polecenia wait, aby zrób to za siebie. Możesz albo przechwycić wszystkie podrzędne identyfikatory procesów i poczekać na nie specjalnie, albo jeśli są to jedyne procesy w tle, które tworzy twój skrypt, możesz po prostu zadzwonić pod numer wait bez argumentu. Na przykład: 
#!/bin/bash # run two processes in the background and wait for them to finish nohup sleep 3 & nohup sleep 10 & echo "This will wait until both are done" date wait date echo "Done" 
Odpowiedź
Kilka punktów:
- 
Jeśli celem
nohupjest zapobieżenie zabiciu procesów roboczych przez zdalne wyjście powłoki, powinieneś użyćnohupw samym skrypcie, a nie w poszczególnych procesach roboczych, które tworzy. - 
Jak wyjaśniono tutaj ,
nohupzapobiega tylko otrzymywaniu przez procesy SIGHUP i od interakcji z terminalem, ale nie przerywa relacji między powłoką a jej procesami potomnymi. - 
Z powodu powyższego punktu, z , prosta
waitpomiędzy dwiemaforpętlami spowoduje, że drugafordo wykonania dopiero po zakończeniu wszystkich procesów potomnych uruchomionych przez pierwszyfor. - 
Za pomocą prostego
wait:oczekiwane są wszystkie aktualnie aktywne procesy potomne, a stan powrotu wynosi zero.
 - 
Jeśli musisz uruchomić drugi
fortylko wtedy, gdy nie było błędów w pierwszym , wtedy „będziesz musiał zapisać każdy PID pracownika za pomocą$!i przekazać je wszystkie dowait:pids= for ... worker ... & pids+=" $!" done wait $pids || { echo "there were errors" >&2; exit 1; } 
Komentarze
-  Jest ld będą innymi zadaniami uruchomionymi na serwerze. Więc ' d chcę tylko czekać na moją partię… są to skrypty R, więc są uruchamiane pod 
Rlubcc1pluswtoppoleceniu - Również ' chciałbym używać nohup w środku aby uruchomić wszystkie polecenia z " parallel ". w zasadzie są to symulacje programu naukowego. Chcę przeprowadzić łącznie 180 symulacji, ale w partiach po 60. Licznik również musi przejść od 1 do 180. Jeśli wykonam je pojedynczo, zajmie to zbyt dużo czasu.
 -  
waitpowoduje, żebashczeka na zadania w tle, które się uruchomiło, nic więcej. Może być tu trochę zamieszania – teforpętle, czy zapisałeś je do pliku i wywołałeś jako skrypt (jak założyłem, z powodu##script), czy też wpisujesz je ręcznie w terminalu? -  robiłem 
cat file.txt | while, a identyfikatory nie zostały ustawione poza pętlą więc polecenie wait zobaczyło pusty ciąg$pids. dlaczego tak się dzieje, omówiono na serverfault.com/q/259339 . łatwo naprawione jakowhile ... < files.txtzgodnie z odpowiedzią na serverfault.com/a/259346 - Po prostu ciekawy jaki jest cel znaku + ze zmienną pids?
 
Odpowiedź
 Użyj fg wbudowany. Czeka do zakończenia procesów w tle. 
 Spróbuj help fg, aby uzyskać szczegółowe informacje. 
Komentarze
- Skrypt działa bez kontroli zadań.
 
Odpowiedź
 Jeśli wstawisz coś takiego jak następujący segment kodu Pomiędzy dwoma pętlami for, może to pomóc. 
flag=0 while [ flag -eq 0 ] do ps -ef | grep "Rscript --vanilla" | grep -v grep > /dev/null flag=${?} sleep 10 done 
 Oczywiście, jeśli aplikacja Rscript ma szansę nie zakończyć się pomyślnie i pozostanie w pobliżu, twoja druga pętla for może nie mieć szansy na uruchomienie. Segment kodu powyżej zakłada, że wszystkie procesy z identyfikatorem Rscript --vanilla zakończą się i znikną prawidłowo. Nie wiedząc, co robi Twoja aplikacja i jak działa, muszę oprzeć się na tym założeniu.
EDYTUJ
W świetle komentarzy lepiej byłoby Twoje potrzeby. (zawiera oryginalny kod oraz logikę sprawdzania ukończenia)
for i in {1..30} do ## append a & if you want to run it parallel; nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" & pids[$i]=${!} done flag=0 while [ flag -eq 0 ] do for PID in $(echo ${pids[@]}) do flag=1 ps -ef | grep ${PID} | grep -v grep >/dev/null; r=${?} if [ ${r} -eq 0 ] then flag=0 fi done done for i in {31..60} do ## append a & if you want to run it parallel; nohup Rscript --vanilla main.R 10 100 $i &> logfile"$i" & done 
Komentarze
-  Proces name w 
toppokazuje czasemRlubcc1plus. -  W takim przypadku będziesz musiał znaleźć wspólny mianownik, który pojawi się na liście 
ps -ef. Lub po każdym poleceniunohupzapisz PID do zmiennej (najlepiej tablicy) przezecho ${!}i sprawdź tę grupę PIDów. Kiedy wszystkie znikną, możesz przejść do drugiejforpętli 
wait.