2012-06-06 22 views
35

Ich möchte ein paar Befehle ausführen, von denen jeder erst beendet wird, wenn Strg-C gedrückt wird. Gibt es etwas, das ich ausführen kann, um alle gleichzeitig auszuführen, und Strg-C wird sie alle beenden? Sie können sich die Terminalausgabe teilen.Parallele Befehle gleichzeitig im selben Terminal ausführen

Insbesondere habe ich den Kompass-Compiler, coffeescript Compiler und einen benutzerdefinierten Befehl, der für Dateiänderungen alle laufenden für Dateiänderungen beobachten beobachtet. Ich möchte kein Terminal für jeden Befehl laden.

Antwort

73

Dieses Bash-Skript ist für N parallele Threads. Jedes Argument ist ein Befehl.

trap wird alle Subprozesse beenden, wenn SIGINT abgefangen wird.
wait $PID_LIST wartet auf den Abschluss jedes Prozesses. Wenn alle Prozesse abgeschlossen sind, wird das Programm beendet.

#!/bin/bash 

for cmd in "[email protected]"; do { 
    echo "Process \"$cmd\" started"; 
    $cmd & pid=$! 
    PID_LIST+=" $pid"; 
} done 

trap "kill $PID_LIST" SIGINT 

echo "Parallel processes have started"; 

wait $PID_LIST 

echo 
echo "All processes have completed"; 

Speichern dieses Skript als parallel_commands und ausführbar machen.
Dies ist, wie dieses Skript zu verwenden:

parallel_commands "cmd arg0 arg1 arg2" "other_cmd arg0 arg2 arg3" 

Beispiel:

parallel_commands "sleep 1" "sleep 2" "sleep 3" "sleep 4" 

Start 4 parallel Schlaf und wartet, bis "Schlaf 4" beendet.

+1

Sehr cool. Trap ist, was ich gesucht habe. Ich habe Ihre Antwort so bearbeitet, dass sie 'wait' enthält, wodurch unnötige" Prozess x exited "Nachrichten unterdrückt werden. –

+1

@MTsoul, 'wait' ist besser als while loop. Ich habe mein Skript mit Ihrem Vorschlag verbessert. Es funktioniert jetzt auch für N parallele Befehle. –

+0

Was ist mit dem Ausführen jedes cmd auf einem einzelnen unterschiedlichen Kern? Sollte ich wie folgt laufen: ./parallel_commands "taskset -c 0 cmd arg0 arg1 arg2" "taskset -c 1 anderes_cmd arg0 arg2 arg3" oder taskset -c 2 ./parallel_commands "taskset -c 0 cmd arg0 arg1 arg2" "taskset -c 1 other_cmd arg0 arg2 arg3 " – user2517676

18

Verwenden GNU Parallel:

(echo command1; echo command2) | parallel 
parallel ::: command1 command2 

zu töten:

parallel ::: command1 command2 & 
PID=$! 
kill -TERM $PID 
kill -TERM $PID 
+1

Dies ist die richtige Antwort. https://www.gnu.org/software/parallel/ – 0atman

+1

@ Oatman: Es sollte, aber GNU Parallel ist nicht in allen Distributionen. Zum Beispiel scheint RHEL 7 kein Paket verfügbar zu haben. –

+0

Ist es möglich, die PID des parallelen Prozesses, der mehrere Prozesse startet, zu verfolgen und sie alle zu beenden, indem Parent Parallels beendet wird? –

1

Ich bin ein viel einfacheres Dienstprogramm was darauf hindeutet, ich gerade schrieb. Es heißt momentan par, wird aber bald in parl oder pll umbenannt, noch nicht entschieden.

https://github.com/k-bx/par

API ist so einfach wie:

par "script1.sh" "script2.sh" "script3.sh" 

prefixing können Befehle über erfolgen:

par "PARPREFIX=[script1] script1.sh" "script2.sh" "script3.sh" 
+1

Nachdem ich versucht habe, das zu tun, was Sie oben mit gnu parallel beschrieben haben, ist es mir gelungen, das erste Mal mit Ihrem Dienstprogramm zu arbeiten. Gute Arbeit! – worldsayshi

+0

Die erste: 'parallel :::" script1.sh "" script2.sh "" script3.sh "' Die zweite würde normalerweise verwenden --tag: 'parallel --tag :::" script1.sh "" script2 .sh "" script3.sh "' –

25

Basierend auf Kommentar von @ alessandro-pezzato, Befehle auszuführen, Multiples, Verwenden Sie einfach & zwischen den Befehlen.

Beispiel:

$ sleep 3 & sleep 5 & sleep 2 & 

Es ist die Befehle im Hintergrund laufen. command1 && command2

Und wenn Sie wollen, laufen sie in zwei verschiedenen Terminals dann tun Sie es wie folgt:

gnome-terminal -e "command1" && gnome-terminal -e "command2" 

Dies öffnet

+0

Dies ist, was ich gesucht habe. –

+0

Ich bekomme einen Fehler, wenn ich nicht das letzte Ausrufezeichen weglassen ... –

+0

Hallo @OleTange, ich kenne den Unterschied nicht. Ich habe '&!' Und '&' ausprobiert und beide haben gleich gut funktioniert. – nsantana

-5

Um mehrere Befehle fügen Sie einfach && zwischen zwei Befehlen wie folgt ausführen 2 Terminals mit command1 und command2 ausführen in ihnen.

Hoffe das hilft dir.

+2

Das ist falsch. Es führt 'command2' ** nach **' command1' und nur wenn 'command1' erfolgreich ist. Versuchen Sie 'sleep 3 && sleep 3' und Sie werden sehen, dass es 6s dauert. –

+0

command1 && command2 startet nicht gleichzeitig. Es wird nacheinander ausgeführt (unter Berücksichtigung des Erfolgsszenarios für den Befehl). – Gahan

Verwandte Themen