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?


8
Verwenden Sie ()diese Option , um den Befehl zu umgeben.
nhahtdh

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.


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 &)

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 &)


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.


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) &

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.


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 &

-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 &
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.