Wie führe ich mehrere Hintergrundbefehle in Bash in einer einzigen Zeile aus?

167

Normalerweise führe ich mehrere Befehle mit so etwas aus:

sleep 2 && sleep 3

oder

sleep 2 ; sleep 3

aber was ist, wenn ich beide im Hintergrund von einem Befehlszeilenbefehl aus ausführen möchte?

sleep 2 & && sleep 3 &

funktioniert nicht Und auch nicht ersetzt &&mit;

Gibt es eine Möglichkeit, dies zu tun?

Palast Chan
quelle
8
Verwenden Sie ()diese Option , um den Befehl zu umgeben.
nhahtdh
1
unix.stackexchange.com/questions/67006/…
Ciro Santilli 5 冠状 病 六四 事件 5

Antworten:

316

Genau wie sollen sie laufen? Wenn Sie möchten, dass sie im Hintergrund gestartet und nacheinander ausgeführt werden , gehen Sie folgendermaßen vor:

(sleep 2; sleep 3) &

Wenn Sie andererseits möchten, dass sie im Hintergrund parallel ausgeführt werden , können Sie stattdessen Folgendes tun:

sleep 2 & sleep 3 &

Und die beiden Techniken könnten kombiniert werden, wie zum Beispiel:

(sleep 2; echo first finished) & (sleep 3; echo second finished) &

Da Bash Bash ist, gibt es oft eine Vielzahl verschiedener Techniken, um dieselbe Aufgabe zu erfüllen, wenn auch manchmal mit subtilen Unterschieden zwischen ihnen.

Kitsune
quelle
20
Dies ist eine prägnante, gut durchdachte Antwort, die "einem Mann das Fischen beibringt". Vielen Dank.
Ambrus
2
Was passiert, wenn wir es tun sleep 2 && sleep 3 &? Ich habe es in Bash versucht und es scheint genauso zu funktionieren (versucht mit Echo).
Wajahat
@HakanBaba, Ja, es wird tatsächlich eine Unterschale im Hintergrund erstellt.
Douwe van der Leest
3
@ Wajahat, hast du es versucht sleep 2 && echo "foo" && sleep 3 & echo "bar""? Der &&Operator weist die Shell an, den Befehl vor ihr auszuführen. Nur wenn dieser Befehl fehlerfrei ausgeführt wird, führt die Shell den nachfolgenden Befehl aus. Dies unterscheidet sich wesentlich von ;, da ;der nachfolgende Befehl unabhängig vom Beendigungsstatus des vorherigen Befehls ausgeführt werden kann, es sei denn, es handelt sich um einen schwerwiegenden Fehler. Das &weist die Shell an, alle "verbundenen" Befehle im Hintergrund auszuführen. "verbunden" bedeutet hier, dass der Befehl Teil einer Pipe ( |) oder eines logischen Operators ist.
Douwe van der Leest
Of these list operators, ‘&&’ and ‘||’ have equal precedence, followed by ‘;’ and ‘&’, which have equal precedence.im Bash-Handbuch.
Jinbeom Hong
49

Sie müssen in Ihrer letzten Version einige Parens hinzufügen -

(sleep 2 &) && (sleep 3 &)

oder das funktioniert auch -

(sleep 2 &) ; (sleep 3 &)
iagreen
quelle
Hinweis: Wenn eine Liste mit verwendet wird &, ist ihr Beendigungsstatus immer Null. Die beiden oben genannten Fälle machen also dasselbe (Die Shell führt beide Seiten der Reihe nach asynchron aus ).
Jinbeom Hong
9

Um mehrere Hintergrundbefehle auszuführen, müssen Sie das &Ende jedes Befehls hinzufügen . Ex: (command1 &) && (command2 &) && (command3 &)

saeed
quelle
5

Die obigen Antworten verwenden Klammern. Bash kann auch Zahnspangen für einen ähnlichen Zweck verwenden:

{ sleep 2 && sleep 3; } &

Beachten Sie, dass die geschweiften Klammern in Bezug auf die Syntax wählerischer sind - das Leerzeichen nach {, das Leerzeichen vor }und das letzte Semikolon sind erforderlich. In einigen Situationen sind die Zahnspangen effizienter, da sie keine neue Unterschale bilden. In diesem Fall weiß ich nicht, ob es einen Unterschied macht.

Greg Reagle
quelle
1
Was ist mit { sleep 2; sleep 3; } &?
Kenny Evitt
4

Das funktioniert:

$(sleep 2 &) && sleep 3 &

Sie können auch:

$(sleep 2 && sleep 3) &
Higuaro
quelle
0

Ich habe auch die gleiche Mission. Ich habe versucht (sleep2 ; fg )& sleep3 ; fg, es funktioniert. Und wenn Sie Strg + C verdoppeln, können die beiden Prozesse gestoppt werden.

Dingyang Wang
quelle
0

Sie können die Ersetzung des Befehls bash folgendermaßen verwenden $(command):

$(command1 ; command2) &

Beachten Sie, dass stdin und stdout weiterhin mit dem übergeordneten Prozess verknüpft sind und das Umleiten mindestens des stdout schwierig sein kann. Alternativ können Sie die Befehle in einer einzigen Zeile verketten und dann die Zeichenfolge an den bashBefehl übergeben, um einen neuen Prozess zu erzeugen, der die Ausführung übernimmt.

bash -c "command1 ; command2" & 

Dies ist besonders in einem Bash-Skript nützlich, wenn Sie mehrere Befehle im Hintergrund ausführen müssen.

Diese beiden Aussagen sollten gleichwertig sein. In beiden Fällen wird ein Bash- Prozess erzeugt, um den Befehl (Befehlskette) zu verarbeiten, und &am Ende wird die Ausführung getrennt.

Dieses Mal können Sie &>/dev/nullvor dem &am Ende des Befehls hinzufügen , um mindestens das stdout umzuleiten und die Ausgabe auf dem stdout des übergeordneten Prozesses zu vermeiden. Etwas wie:

bash -c "command1 ; command2" &>/dev/null &
Bemipefe
quelle
-1

Wenn Sie mehrere Befehle nacheinander ausführen möchten , gibt es eine wirklich einfache Methode, die überall funktioniert: Erstellen einer Datei! Der Vorteil dieser Methode ist, dass sie sauber und einfach ist.

Erstellen Sie zunächst Ihre Datei mit einem Namen, z commands.sh. Dann setzen Sie Ihre Befehle dort. Hier ist ein Beispiel:

commands.sh:

#!/system/bin/sh

sleep 3;
sleep 2;

OK, jetzt sind wir im letzten Schritt. Um Befehle im Hintergrund (nacheinander) auszuführen, führen Sie einfach Folgendes aus:

$ sh commands.sh &
MAChitgarha
quelle