Mam skrypt bash, 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, aby pierwszy zestaw zadań zakończył się przed rozpoczęciem nowego zestawu. Ale z tego nohup
powodu wydaje się, że wszystkie działają jednocześnie.
Mam, nohup
ponieważ zdalnie loguję się na mój serwer i uruchamiam tam zadania, a następnie zamykam bash. Czy istnieje alternatywne rozwiązanie?
wait
wbudowane.Odpowiedzi:
Będziesz chciał użyć tego
wait
polecenia, aby zrobić to za Ciebie. Możesz przechwycić wszystkie identyfikatory procesów potomnych i poczekać na nie, lub jeśli są to jedyne procesy w tle tworzone przez skrypt, możesz po prostu zadzwonićwait
bez argumentu. Na przykład:źródło
Kilka punktów:
Jeśli Twoim celem
nohup
jest zapobieganie zabijaniu procesów roboczych przez zdalną powłokę, powinieneś użyćnohup
samego skryptu, a nie poszczególnych tworzonych przez niego procesów roboczych.Jak wyjaśniono tutaj ,
nohup
tylko uniemożliwia procesom otrzymywanie SIGHUP i interakcję z terminalem, ale nie przerywa relacji między powłoką a jej procesami potomnymi.Z powodu powyższego punktu, z lub bez
nohup
, prostawait
między dwiemafor
pętlami spowoduje, że drugafor
zostanie wykonana dopiero po zakończeniu wszystkich procesów potomnych rozpoczętych przez pierwsząfor
.Prostym
wait
:Jeśli musisz uruchomić drugi,
for
tylko jeśli nie wystąpiły błędy w pierwszym, musisz zapisać każdy identyfikator PID pracownika$!
i przekazać je wszystkimwait
:źródło
R
lubcc1plus
wtop
komendziewait
powodujebash
oczekiwanie na zadania w tle, które sam się pojawił, nic więcej. Może to być pewne zamieszanie - tefor
pętle, czy zapisałeś je do pliku i wywołałeś jako skrypt (co założyłem, ze względu na##script
linię), czy wpisujesz je ręcznie w terminalu?Użyj
fg
wbudowanego. Czeka na zakończenie procesów w tle.Spróbuj
help fg
po szczegóły.źródło
Jeśli wstawisz coś takiego jak poniższy segment kodu między dwiema
for
pętlami, może to pomóc.Oczywiście, jeśli Twoja aplikacja
Rscript
ma szansę nie ukończyć się pomyślnie i pozostać w tyle, druga pętla for może nie mieć szansy na uruchomienie. Powyższy segment kodu zakłada, że wszystkie procesy z identyfikatoremRscript --vanilla
zakończą się i znikną poprawnie. Nie wiedząc, co robi Twoja aplikacja i jak działa, muszę polegać na tym założeniu.EDYTOWAĆ
W świetle komentarzy lepiej to spełni twoje potrzeby. (zawiera twój oryginalny kod, a także logikę sprawdzania ukończenia)
źródło
top
pokazuje alboR
czasami albocc1plus
.ps -ef
liście. Lub po każdymnohup
poleceniu zapisz PID do zmiennej (najlepiej tablicy) wedługecho ${!}
i sprawdź tę grupę PID. Gdy wszystkie znikną, możesz przejść do drugiejfor
pętli