Ejecute comandos en paralelo y espere a que termine un grupo de comandos antes de comenzar el siguiente

12

Tengo script que incluye múltiples comandos. ¿Cómo puedo agrupar comandos para que se ejecuten juntos? (Quiero hacer varios grupos de comandos. Dentro de cada grupo, los comandos deben ejecutarse en paralelo (al mismo tiempo). Los grupos deben ejecutarse secuencialmente, esperando que un grupo termine antes de comenzar siguiente grupo) ... es decir

#!/bin/bash
command #1
command #2
command #3
command #4
command #5
command #6
command #7
command #8
command #9
command #10

¿Cómo puedo ejecutar cada 3 comandos para gether? Lo intenté:

#!/bin/bash
{
command #1
command #2
command #3
} & 
{   
command #4
command #5
command #6
} & 
{
command #7
command #8
command #9
}&
command #10

Pero esto no funcionó correctamente (quiero ejecutar los grupos de comandos en paralelo al mismo tiempo. También necesito esperar a que termine el primer grupo antes de ejecutar el siguiente grupo)

¡El script está saliendo con un mensaje de error!

RobertL
fuente
2
¿Qué quieres decir con correr juntos? ¿Te refieres a correr en paralelo al mismo tiempo? ¿Cómo sabes que "no funcionó correctamente"? ¿Cómo sabrá cuándo funciona correctamente? ¿Desea esperar a que termine el primer grupo antes de ejecutar el siguiente grupo?
RobertL
@ RobertL. Sí, quiero decir en paralelo al mismo tiempo. El script está saliendo con un mensaje de error. Sí, tengo que esperar a que termine el primer grupo antes de ejecutar el siguiente grupo.
1
@goro citandote, el script está saliendo con un mensaje de error. Edite su pregunta para agregar dicho mensaje (por el bien de la finalización) y elimine el chit-chat (consejos apreciados).
dave_alcarin
¿Es el mismo comando ejecutándose en cada instancia? ¿Mismo nombre?
RobertL
1
@goro, ¿es esto correcto? "Tiene varios grupos de comandos. Dentro de cada grupo, los comandos deben ejecutarse en paralelo (al mismo tiempo). Los grupos deben ejecutarse secuencialmente, esperando que un grupo termine antes de comenzar el siguiente grupo".
RobertL

Respuestas:

20

Los comandos dentro de cada grupo se ejecutan en paralelo, y los grupos se ejecutan secuencialmente, cada grupo de comandos paralelos espera que el grupo anterior termine antes de comenzar la ejecución.

El siguiente es un ejemplo de trabajo:

Asuma 3 grupos de comandos como en el código a continuación. En cada grupo, los tres comandos se inician en segundo plano con &.

Los 3 comandos se iniciarán casi al mismo tiempo y se ejecutarán en paralelo mientras el script waitstermina.

Después de los tres comandos en la salida del tercer grupo, command 10se ejecutará.

$ cat command_groups.sh 
#!/bin/sh

command() {
    echo $1 start
    sleep $(( $1 & 03 ))      # keep the seconds value within 0-3
    echo $1 complete
}

echo First Group:
command 1 &
command 2 &
command 3 &
wait

echo Second Group:
command 4 &
command 5 &
command 6 &
wait

echo Third Group:
command 7 &
command 8 &
command 9 &
wait

echo Not really a group, no need for background/wait:
command 10

$ sh command_groups.sh 
First Group:
1 start
2 start
3 start
1 complete
2 complete
3 complete
Second Group:
4 start
5 start
6 start
4 complete
5 complete
6 complete
Third Group:
7 start
8 start
9 start
8 complete
9 complete
7 complete
Not really a group, no need for background/wait:
10 start
10 complete
$   
RobertL
fuente
Sin embargo, creo que los curlies no tienen sentido en tu ejemplo. La espera es un proceso global, y los grupos rizados no crearán una nueva bifurcación en este caso.
PSkocik
1
@PSkocik, cierto. Órganos vestigiales.
RobertL
6
{
command #1
command #2
command #3
} & 
{   
command #4
command #5
command #6
} & 
{
command #7
command #8
command #9
}&
command #10
wait #<===

Debería funcionar (cada componente de triplete individual se ejecutará secuencialmente, pero los grupos se ejecutarán en paralelo). Probablemente no desee que su shell principal salga antes de que los grupos hayan terminado, de ahí el wait.

PSkocik
fuente
2
La pregunta original decía solo "ejecutar cada 3 comandos juntos". Sin aclaración, cualquiera de las respuestas es correcta. Buena llamada al wait.
RobertL