Ich habe ein Bash-Skript, das wie folgt aussieht:
##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
Ich möchte eine weitere for-Schleife nach der ersten erstellen, um für weitere 30 fortzufahren. Zum Beispiel
##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
Ich möchte, dass der erste Auftragssatz beendet wird, bevor der neue Satz gestartet wird. Aber wegen dem nohup
scheint es, dass sie alle gleichzeitig laufen.
Ich habe, nohup
weil ich mich remote auf meinem Server anmelde und die Jobs dort starte und dann meine Bash schließe. Gibt es eine alternative Lösung?
wait
Durchsuchen Sie das Handbuch nach dem eingebauten.Antworten:
Sie möchten den
wait
Befehl verwenden, um dies für Sie zu tun. Sie können entweder alle untergeordneten Prozess-IDs erfassen und gezielt auf sie warten, oder Sie können siewait
ohne Argumente aufrufen, wenn sie die einzigen Hintergrundprozesse sind, die Ihr Skript erstellt . Beispielsweise:quelle
Ein paar Punkte:
Wenn Sie mit
nohup
verhindern möchten, dass ein Remote-Shell-Exit Ihre Worker-Prozesse beendet, sollten Sie diesnohup
für das Skript selbst und nicht für die einzelnen von ihm erstellten Worker-Prozesse verwenden.Wie hier erläutert , wird
nohup
nur verhindert , dass Prozesse SIGHUP empfangen und mit dem Terminal interagieren. Die Beziehung zwischen der Shell und ihren untergeordneten Prozessen wird jedoch nicht unterbrochen.Aufgrund des obigen Punktes mit oder ohne
nohup
wird eine einfachewait
Zwischenschleifefor
dazu führen, dass die zweite Schleifefor
erst ausgeführt wird, nachdem alle untergeordneten Prozesse, die von der ersten gestartet wurden, beendetfor
wurden.Mit einem einfachen
wait
:Wenn Sie die zweite
for
nur ausführen müssen, wenn in der ersten keine Fehler aufgetreten sind, müssen Sie jede Arbeiter-PID mit speichern$!
und sie alle übergeben anwait
:quelle
R
odercc1plus
in demtop
Befehlwait
bewirktbash
, dass auf die Hintergrundjobs gewartet wird, die er selbst erzeugt hat, sonst nichts. Hier könnte es zu Verwirrung kommen - diesefor
Schleifen, haben Sie sie in einer Datei gespeichert und als Skript aufgerufen (was ich aufgrund der##script
Zeile angenommen habe), oder tippen Sie sie manuell im Terminal ein?Verwenden Sie das
fg
eingebaute. Es wird gewartet, bis die Hintergrundprozesse beendet sind.Versuchen Sie es
help fg
für Details.quelle
Wenn Sie so etwas wie das folgende Codesegment zwischen Ihre beiden
for
Schleifen einfügen , kann dies hilfreich sein.Wenn Ihre Anwendung
Rscript
möglicherweise nicht erfolgreich abgeschlossen wird und nicht lange ausgeführt wird, hat Ihre zweite for-Schleife möglicherweise keine Chance, ausgeführt zu werden. Das obige Codesegment geht davon aus, dass alle Prozesse mit dem BezeichnerRscript --vanilla
ordnungsgemäß abgeschlossen werden und verschwinden. Ohne zu wissen, was Ihre Anwendung macht und wie sie läuft, muss ich mich auf diese Annahme verlassen.BEARBEITEN
In Anbetracht der Kommentare würde dies Ihren Bedürfnissen besser entsprechen. (Es enthält Ihren Originalcode sowie die Logik für die Abschlussprüfung.)
quelle
top
wird entwederR
manchmal oder angezeigtcc1plus
.ps -ef
Liste angezeigt wird. Odernohup
zeichnen Sie nach jedem Befehl die PID in einer Variablen (vorzugsweise einem Array) aufecho ${!}
und suchen Sie nach dieser Gruppe von PIDs. Wenn sie alle verschwinden, können Sie in die zweite gehenfor
Schleife