Einen Bash-Befehl nach einigen gleichzeitigen Befehlen ausführen?
13
Ich möchte einige Befehle parallel ausführen. Wenn alle diese Befehle beendet sind, starten Sie den nächsten. Ich denke, der folgende Ansatz wird funktionieren
wait (ohne Argumente) wird warten, bis alle Prozesse im Hintergrund beendet wurden.
Die vollständige Beschreibung waitim bashHandbuch:
wait [-n] [n ...]
Warten Sie auf jeden angegebenen untergeordneten Prozess und geben Sie seinen Beendigungsstatus zurück. Jedes nkann eine Prozess-ID oder eine Auftragsspezifikation sein. Wird eine Jobspezifikation angegeben, wird auf alle Prozesse in der Pipeline dieses Jobs gewartet. Wenn nnicht angegeben, wird auf alle derzeit aktiven untergeordneten Prozesse gewartet, und der Rückgabestatus ist Null. Wenn die
-nOption angegeben ist, wird darauf waitgewartet, dass ein Auftrag beendet wird, und der Beendigungsstatus wird zurückgegeben. Wenn nein nicht vorhandener Prozess oder Job angegeben ist, lautet der Rückgabestatus 127. Andernfalls ist der Rückgabestatus der Beendigungsstatus des letzten Prozesses oder Jobs, auf den gewartet wurde.
Eine andere Möglichkeit ist, die PID jedes Kindes mit etwas wie zu speichern PID1=$!und dann auf alle mit zu warten wait "$PID1" "$PID2" "$PID3". Das ist etwas komplizierter, funktioniert aber, wenn der Prozess andere Kinder hat, auf die Sie nicht warten möchten.
Kasperd
1
@kasperd Besser mit einem Array in diesem Fall: cmd1 & pids=( $! ); cmd2 & pids+=( $! ); cmd3 & pids+=( $! ); wait "${pids[@]}"oder so ähnlich.
Kusalananda
@kasperd Mit "besser" meine ich "benutze nur eine Variable". An sich nichts falsches daran, viele zu verwenden, und wahrscheinlich ist es für kleine Fälle wie diesen völlig in Ordnung.
Kusalananda
0
Ich mag die waitAntwort, aber nur als akademische Übung denke ich, dass dies auch funktionieren würde:
Hast du das getestet? Es funktioniert absolut nicht. Beispiel: time bash -c "sleep 5 &sleep 5 &sleep 5 &" && echo foo Wenn nicht angegeben wird, dass der Befehl bash fünf Sekunden gedauert hat, hat er nicht das getan, was Sie wollen.
Seth Robertson
Ich habe es mit Schlaf und Echos getestet und es schien zu funktionieren. Ihr Beispiel beweist das Gegenteil.
PID1=$!
und dann auf alle mit zu wartenwait "$PID1" "$PID2" "$PID3"
. Das ist etwas komplizierter, funktioniert aber, wenn der Prozess andere Kinder hat, auf die Sie nicht warten möchten.cmd1 & pids=( $! ); cmd2 & pids+=( $! ); cmd3 & pids+=( $! ); wait "${pids[@]}"
oder so ähnlich.Ich mag die
wait
Antwort, aber nur als akademische Übung denke ich, dass dies auch funktionieren würde:Bitte korrigieren Sie mich, wenn ich falsch liege.
quelle
time bash -c "sleep 5 &sleep 5 &sleep 5 &" && echo foo
Wenn nicht angegeben wird, dass der Befehl bash fünf Sekunden gedauert hat, hat er nicht das getan, was Sie wollen.