Führen Sie denselben Befehl mehrmals im Hintergrund aus

13

Wie ist es möglich, mehrere Befehle mit bash auszuführen und im Hintergrund anzuzeigen?

Beispielsweise:

$ for i in {1..10}; do wait file$i &; done

Warten ist eine benutzerdefinierte Binärdatei.

Im Moment erhalte ich eine Fehlermeldung:

syntax error near unexpected token `;'

beim Ausführen des obigen Befehls.

Nach dem Hintergrund sollten die Befehle parallel ausgeführt werden.

Sebi
quelle
1
Ich beziehe mich nicht auf: nohupErmöglichen, dass Sie einen Befehl im Hintergrund ausführen
Dave Hamilton
3
Der Fehler, den Sie sehen, beruht auf &und ;ist beides "Befehlsabschlusszeichen". Sie müssen nicht beide verwenden: for ...; do wait $arg & donefunktioniert.
Glenn Jackman
@ Glenn Jackman. Ja, ich habe es tatsächlich versucht, nachdem ich die Frage gestellt habe. Es gibt keine Notwendigkeit für beide; und &
Sebi
3
Für zukünftige Leser ein Link zur Dokumentation : "Eine Liste ist eine Folge von einer oder mehreren Pipelines, die durch einen der Operatoren ';', '&', '&&' oder '||' getrennt und optional durch einen abgeschlossen werden von ';', '&' oder einem Zeilenumbruch. " (Hervorhebung meiner)
Glenn Jackman
stackoverflow.com/q/14753491/560648
Leichtigkeit Rennen mit Monica

Antworten:

20

Das &ist genau wie ;ein Listenabschlussoperator . Sie haben dieselbe Syntax und können austauschbar verwendet werden (je nachdem, was Sie tun möchten). Das bedeutet, dass Sie nicht nur wollen oder brauchen, sondern command1 &; command2nur command1 & command2.

In Ihrem Beispiel könnten Sie also einfach schreiben:

for i in {1..10}; do wait file$i & done

und jeder waitBefehl wird im Hintergrund gestartet und die Schleife fährt sofort mit dem nächsten fort.

terdon
quelle
4

Verwenden Sie aus Kompatibilitätsgründen die Posix-Form anstelle der Erweiterung:

for i in $(seq 1 10); do (./wait file$i &); done
Marc
quelle
1
Beachten Sie, dass dies seqkein POSIX-Befehl ist und im Allgemeinen nur auf GNU-Systemen vorkommt. Das Verhalten oder $(...)(und $i) hängt vom aktuellen Wert von ab $IFS. Beachten Sie auch , dass , indem Sie (cmd &), cmdwird ein Kind von einer Subshell sein, so werden Sie nicht in der Lage sein , zu warten und ihren Exit - Status zum Beispiel erhalten.
Stéphane Chazelas
2

Sie können die Befehle gruppieren und die gruppierten Befehle in den Hintergrund stellen. Mögen :

$ for i in {1..10}; do ((wait file$i)&); done
Labyrinthe
quelle
Es ist nicht erforderlich, die inneren Klammern zu verwenden ...
Marc
Sie müssen nur die inneren Klammern verwenden, wenn Sie mehrere in der Frage gestellte Befehle in den Hintergrund stellen möchten. Like ((sleep 1; warte Datei $ i) &);
Mazs
2

Ist Ihre Binärdatei wirklich benannt wait? Ich empfehle dies nicht, da waites sich um eine eingebaute Shell handelt.

Ich glaube, dass bash eine einzeilige Schleife, die Hintergrundprozesse startet, nicht gut parst. Ich empfehle Ihnen, den Code zu ändern:

$ for i in {1..10}; do ./wait file$i & echo "Running 'wait' using PID=$!..."; done
Anderson Medeiros Gomes
quelle