Estoy tratando de escribir un archivo .sh que ejecute muchos programas simultáneamente
Probé esto
prog1
prog2
Pero eso ejecuta prog1 luego espera hasta que termine prog1 y luego comienza prog2 ...
Entonces, ¿cómo puedo ejecutarlos en paralelo?
bash
parallel-processing
Betamoo
fuente
fuente
wait
! Sí, en bash puedes esperar los procesos secundarios del script.nohup
para evitar que el programa se elimine cuando el shell cuelga.Qué tal si:
Esta voluntad:
prog1
.prog2
y manténgalo en primer plano , para que pueda cerrarloctrl-c
.prog2
, volverá aprog1
's primer plano , por lo que puede también cerca conctrl-c
.fuente
prog1
cuandoprog2
termina? Piense ennode srv.js & cucumberjs
prog1 & prog2 ; fg
esto fue para ejecutar múltiples túneles ssh a la vez. Espero que esto ayude a alguien.prog2
no se ejecuta de inmediato, volverá a tenerprog1
el primer plano. Si esto es deseable, entonces está bien.prog1 & prog2 && kill $!
.Puedes usar
wait
:Asigna los PID del programa en segundo plano a las variables (
$!
es el último PID del proceso iniciado), luego elwait
comando los espera. Es bueno porque si matas el script, también mata los procesos.fuente
#!/usr/bin/env bash ARRAY='cat bat rat' for ARR in $ARRAY do ./run_script1 $ARR & done P1=$! wait $P1 echo "INFO: Execution of all background processes in the for loop has completed.."
${}
para interpolarlo en una lista de cadenas o similar.Con GNU Parallel http://www.gnu.org/software/parallel/ es tan fácil como:
O si lo prefieres:
Aprende más:
fuente
parallel
con diferentes sintaxis. Por ejemplo, en los derivados de Debian, elmoreutils
paquete contiene un comando diferente llamadoparallel
que se comporta de manera bastante diferente.parallel
mejor que usar&
?parallel
es mejor cuando hay más trabajos que núcleos, en cuyo caso&
ejecutaría más de un trabajo por núcleo a la vez. (cf. principio del casillero )Si desea poder ejecutar y eliminar fácilmente múltiples procesos
ctrl-c
, este es mi método favorito: generar múltiples procesos en segundo plano en una(…)
subshell y capturarSIGINT
para ejecutarkill 0
, lo que matará todo lo generado en el grupo de subshell:Puede tener estructuras de ejecución de proceso complejas, y todo se cerrará con una sola
ctrl-c
(solo asegúrese de que el último proceso se ejecute en primer plano, es decir, no incluya un&
despuésprog1.3
):fuente
xargs -P <n>
le permite ejecutar<n>
comandos en paralelo.Si bien
-P
es una opción no estándar, tanto las implementaciones GNU (Linux) como macOS / BSD lo admiten.El siguiente ejemplo:
El resultado se parece a:
El tiempo muestra que los comandos se ejecutaron en paralelo (el último comando se lanzó solo después de que finalizó el primero de los 3 originales, pero se ejecutó muy rápidamente).
El
xargs
comando en sí no volverá hasta que todos los comandos hayan terminado, pero puede ejecutarlo en segundo plano al terminarlo con el operador de control&
y luego usar elwait
incorporado para esperarxargs
a que termine todo el comando.Nota:
BSD / macOS
xargs
requiere que especifique el recuento de comandos para ejecutar en paralelo explícitamente , mientras que GNU lexargs
permite especificar-P 0
ejecutar tantos como sea posible en paralelo.La salida de los procesos ejecutados en paralelo llega a medida que se genera , por lo que se intercalará de forma impredecible .
parallel
, como se menciona en la respuesta de Ole ( no viene estándar con la mayoría de las plataformas), serializa (agrupa) convenientemente la salida por proceso y ofrece muchas características más avanzadas.fuente
Redirigir errores para separar los registros.
fuente
prog1 2> .errorprog1.log & prog2 2> .errorprog2.log &
ls notthere1 & 2> .errorprog1.log; ls notthere2 & 2>.errorprog2.log
. Los errores van a la consola y ambos archivos de errores están vacíos. Como dice @Dennis Williamson,&
es un separador,;
por lo que (a) debe ir al final del comando (después de cualquier redirección), y (b) no necesita;
nada :-)Hay un programa muy útil que llama nohup.
fuente
nohup
por sí solo no ejecuta nada en segundo plano, y el usonohup
no es un requisito o requisito previo para ejecutar tareas en segundo plano. A menudo son útiles juntos, pero como tal, esto no responde la pregunta.Aquí hay una función que uso para ejecutar al máximo el proceso n en paralelo (n = 4 en el ejemplo):
Si max_children se establece en el número de núcleos, esta función intentará evitar los núcleos inactivos.
fuente
wait -n
requierebash
4.3+ y cambia la lógica para esperar a que finalice cualquiera de los procesos especificados / implícitos.Puedes probar ppss . ppss es bastante poderoso, incluso puedes crear un mini-cluster. xargs -P también puede ser útil si tienes que hacer un lote de procesamiento embarazosamente paralelo.
fuente
Recientemente tuve una situación similar en la que necesitaba ejecutar varios programas al mismo tiempo, redirigir sus salidas a archivos de registro separados y esperar a que terminaran y terminé con algo así:
Fuente: http://joaoperibeiro.com/execute-multiple-programs-and-redirect-their-outputs-linux/
fuente
Gerente de proceso de desove
Claro, técnicamente estos son procesos, y este programa realmente debería llamarse un administrador de generación de procesos, pero esto solo se debe a la forma en que BASH funciona cuando se bifurca usando el ampersand, usa la llamada al sistema fork () o quizás clone () que clona en un espacio de memoria separado, en lugar de algo como pthread_create () que compartiría memoria. Si BASH admitiera lo último, cada "secuencia de ejecución" funcionaría de la misma manera y podría denominarse subprocesos tradicionales al tiempo que obtendría una huella de memoria más eficiente. Funcionalmente, sin embargo, funciona de la misma manera, aunque un poco más difícil ya que las variables GLOBALES no están disponibles en cada clon de trabajo, por lo tanto, el uso del archivo de comunicación entre procesos y el semáforo rudimentario de bandadas para gestionar secciones críticas. Bifurcar desde BASH, por supuesto, es la respuesta básica aquí, pero siento que la gente lo sabe, pero realmente está buscando administrar lo que se genera en lugar de simplemente bifurcarlo y olvidarlo. Esto demuestra una manera de administrar hasta 200 instancias de procesos bifurcados, todos accediendo a un solo recurso. Claramente, esto es excesivo, pero disfruté escribirlo, así que seguí. Aumente el tamaño de su terminal en consecuencia. Espero que encuentres esto útil.
fuente
Su guión debería verse así:
Asumiendo que su sistema puede tomar n trabajos a la vez. use esperar para ejecutar solo n trabajos a la vez.
fuente
Con bashj ( https://sourceforge.net/projects/bashj/ ), debería poder ejecutar no solo múltiples procesos (como lo sugirieron otros) sino también múltiples subprocesos en una JVM controlada desde su script. Pero, por supuesto, esto requiere un Java JDK. Los subprocesos consumen menos recursos que los procesos.
Aquí hay un código de trabajo:
fuente