2012-06-06 16 views
35

Quiero ejecutar algunos comandos, cada uno de los cuales no se cierra hasta que se presiona Ctrl-C. ¿Hay algo que pueda ejecutar para ejecutarlos todos a la vez, y Ctrl-C los abandonará a todos? Pueden compartir la salida del terminal.Ejecutar múltiples comandos paralelos a la vez en el mismo terminal

Específicamente, tengo el compilador de brújula, el compilador de coffeescript y un comando personalizado que observa los cambios de archivos y todos están viendo los cambios de archivos. No quiero cargar una terminal para cada comando.

Respuesta

73

Este script bash es para N hilos paralelos. Cada argumento es un comando.

trap matará a todos los subprocesos cuando SIGINT está atrapado.
wait $PID_LIST está esperando cada proceso para completar. Cuando se hayan completado todos los procesos, el programa finaliza.

#!/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"; 

Guardar este script como parallel_commands y que sea ejecutable.
Esto es cómo utilizar esta secuencia de comandos:

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

Ejemplo:

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

inicio del sueño 4 paralelos y espera hasta que termine el sueño "4".

+1

Muy bueno. Trap es lo que estaba buscando. Edité tu respuesta para incluir 'wait', que suprimirá mensajes innecesarios de" proceso x exit ". –

+1

@MTsoul, 'wait' es mejor que while loop. He mejorado mi script con tu sugerencia. También funciona para N comandos paralelos ahora. –

+0

¿Qué hay de ejecutar cada cmd en un único núcleo distinto? ¿Debería ejecutar como: ./parallel_commands "taskset -c 0 cmd arg0 arg1 arg2" "taskset -c 1 other_cmd arg0 arg2 arg3" o taskset -c 2 ./parallel_commands "taskset -c 0 cmd arg0 arg1 arg2" "taskset -c 1 other_cmd arg0 arg2 arg3 " – user2517676

18

uso de GNU en paralelo:

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

para matar:

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

Esta es la respuesta correcta. https://www.gnu.org/software/parallel/ – 0atman

+1

@Oatman: debería ser, pero GNU paralelo no está en todas las distribuciones. Por ejemplo, RHEL 7 no parece tener un paquete disponible. –

+0

¿Es posible rastrear el PID del proceso paralelo que inicia múltiples procesos y terminarlos todos terminando el paralelo padre? –

1

que estoy sugiriendo una utilidad mucho más simple que acabo de escribir. Actualmente se llama par, pero se cambiará de nombre pronto a parl o pll, aún no se ha decidido.

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

API es tan simple como:

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

anteponiendo comandos se puede hacer a través de:

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

Después de intentar y dejar de hacer lo que describe arriba usando gnu parallel lo logré al primer intento usando su utilidad. ¡Buen trabajo! – worldsayshi

+0

El primero: 'parallel :::" script1.sh "" script2.sh "" script3.sh "' El segundo normalmente usaría --tag: 'parallel --tag :::" script1.sh "" script2 .sh "" script3.sh "' –

25

Basado en el comentario de @ alessandro-Pezzato, para ejecutar comandos múltiples, solo use &, entre los comandos.

Ejemplo:

$ sleep 3 & sleep 5 & sleep 2 & 

Es ejecutará los comandos en segundo plano.

+0

Esto es lo que estaba buscando. –

+0

Me sale un error a menos que omita el signo de exclamación final ... –

+0

Hola @OleTange, no sé la diferencia. Intenté '&!' Y '&' y ambos funcionaron por igual. – nsantana

-5

Para ejecutar varios comandos sólo tiene que añadir && entre dos comandos de la siguiente manera: command1 && command2

Y si desea ejecutar en dos terminales diferentes, entonces lo hacen así:

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

Esto abrirá 2 terminales con command1 y command2 ejecutándose en ellos.

Espero que esto te ayude.

+2

Esto es incorrecto. Ejecuta 'command2' ** después de **' command1' y solo si 'command1' tiene éxito. Prueba 'sleep 3 && sleep 3' y verás que tarda 6s. –

+0

command1 && command2 no comienza a ejecutarse de inmediato. se ejecutará uno tras otro (considerando el escenario de éxito para el comando). – Gahan

Cuestiones relacionadas