Exécuter une commande bash après quelques commandes simultanées?

13

Je veux exécuter quelques commandes en parallèle. Lorsque toutes ces commandes sont terminées, démarrez la suivante. Je pense que l'approche suivante fonctionnera

#!/bin/bash
command1 &
command2 &
command3 &&
command4

mais ce ne fut pas le cas. Je dois exécuter command4lorsque les trois premières commandes sont terminées.

Googlebot
la source

Réponses:

28
#!/bin/bash
command1 &
command2 &
command3 &

wait
command4

wait (sans aucun argument) attendra la fin de tous les processus en arrière-plan.

La description complète de waitdans le bashmanuel:

wait [-n] [n ...]

Attendez chaque processus enfant spécifié et retournez son état de terminaison. Chacun npeut être un ID de processus ou une spécification de travail; si une spécification de travail est donnée, tous les processus du pipeline de ce travail sont attendus. Si nn'est pas indiqué, tous les processus enfants actuellement actifs sont attendus et l'état de retour est zéro. Si l' -noption est fournie, waitattend la fin de tout travail et renvoie son état de sortie. Si nspécifie un processus ou un travail inexistant, l'état de retour est 127. Sinon, l'état de retour est l'état de sortie du dernier processus ou travail attendu.

Kusalananda
la source
1
Une autre option consiste à enregistrer le PID de chaque enfant à l'aide de quelque chose comme PID1=$!, puis à attendre tous avec wait "$PID1" "$PID2" "$PID3". C'est un peu plus compliqué, mais cela fonctionnera si le processus a d'autres enfants que vous ne voulez pas attendre.
kasperd
1
@kasperd Mieux avec un tableau dans ce cas: cmd1 & pids=( $! ); cmd2 & pids+=( $! ); cmd3 & pids+=( $! ); wait "${pids[@]}"ou quelque chose de similaire.
Kusalananda
@kasperd Par "mieux", je veux dire "n'utilise qu'une seule variable". Rien de mal en soi à en utiliser plusieurs, et est probablement tout à fait correct pour les petits cas comme celui-ci.
Kusalananda
0

J'aime la waitréponse, mais tout comme un exercice académique, je pense que cela fonctionnerait aussi:

bash -c 'command1 & command2 & command3 &' && command4

S'il vous plait corrigez moi si je me trompe.

Burger
la source
2
Avez-vous testé cela? Cela ne fonctionne absolument pas. Exemple: time bash -c "sleep 5 &sleep 5 &sleep 5 &" && echo foo S'il ne dit pas que la commande bash a pris cinq secondes, elle n'a pas fait ce que vous vouliez.
Seth Robertson
Je l'ai testé avec du sommeil et des échos et cela semblait fonctionner. Votre exemple prouve le contraire.
burger