ejecutar un script en varias carpetas en paralelo

ejecutar un script en varias carpetas en paralelo

Tengo varios subdirectorios dentro de un directorio de alto nivel. Cada subdirectorio tiene varios archivos y un script de shell de bucle for. El mismo script de bucle for está presente en cada subdirectorio. Quiero ir a cada subdirectorio y ejecutar el script de bucle for en paralelo en varias terminales. Intenté esto pero parece funcionar en serie (uno tras otro), pero quiero ejecutarlos todos en paralelo.

find dir_* -type f -execdir sh for_loop.sh {} \;

Respuesta1

Suponiendo que esto haga lo correcto, solo en serie:

find dir_* -type f -execdir sh for_loop.sh {} \;

Entonces deberías poder reemplazar eso con:

find dir_* -type f | parallel 'cd {//} && sh for_loop.sh {}'

Para ejecutarlo en múltiples terminales, GNU Parallel admite tmuxejecutar cada comando en su propio tmuxpanel:

find dir_* -type f | parallel --tmuxpane 'cd {//} && sh for_loop.sh {}'

El valor predeterminado es un trabajo por núcleo de CPU. En su caso, es posible que desee ejecutar un trabajo más de los que tiene núcleos:

 find dir_* -type f | parallel -j+1 --tmuxpane 'cd {//} && sh for_loop.sh {}'

GNU Parallel es un paralelizador general y facilita la ejecución de trabajos en paralelo en la misma máquina o en varias máquinas a las que tiene acceso ssh.

Si tiene 32 trabajos diferentes que desea ejecutar en 4 CPU, una forma sencilla de paralelizar es ejecutar 8 trabajos en cada CPU:

Programación sencilla

En cambio, GNU Parallel genera un nuevo proceso cuando uno finaliza, manteniendo las CPU activas y, por lo tanto, ahorrando tiempo:

Programación paralela GNU

Instalación

Por razones de seguridad, debe instalar GNU Parallel con su administrador de paquetes, pero si GNU Parallel no está empaquetado para su distribución, puede realizar una instalación personal, que no requiere acceso de root. Se puede hacer en 10 segundos haciendo esto:

$ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
   fetch -o - http://pi.dk/3 ) > install.sh
$ sha1sum install.sh | grep 883c667e01eed62f975ad28b6d50e22a
12345678 883c667e 01eed62f 975ad28b 6d50e22a
$ md5sum install.sh | grep cc21b4c943fd03e93ae1ae49e28573c0
cc21b4c9 43fd03e9 3ae1ae49 e28573c0
$ sha512sum install.sh | grep da012ec113b49a54e705f86d51e784ebced224fdf
79945d9d 250b42a4 2067bb00 99da012e c113b49a 54e705f8 6d51e784 ebced224
fdff3f52 ca588d64 e75f6033 61bd543f d631f592 2f87ceb2 ab034149 6df84a35
$ bash install.sh

Para otras opciones de instalación consultehttp://git.savannah.gnu.org/cgit/parallel.git/tree/README

Aprende más

Ver más ejemplos:http://www.gnu.org/software/parallel/man.html

Mira los vídeos de introducción:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Sigue el tutorial:http://www.gnu.org/software/parallel/parallel_tutorial.html

Regístrese en la lista de correo electrónico para obtener ayuda:https://lists.gnu.org/mailman/listinfo/parallel

Respuesta2

Probablemente la herramienta perfecta para esto seaParalelo GNU:

parallel ::: dir_*/for_loop.sh

GNU Parallel no sólo ejecuta cada trabajo en paralelo, sino que también demultiplexa su salida para que no interfieran entre sí.

Desde su página de manual:

GNU paralelo es una herramienta de shell para ejecutar trabajos en paralelo utilizando una o más computadoras. Un trabajo puede ser un comando único o un pequeño script que debe ejecutarse para cada una de las líneas de la entrada. La entrada típica es una lista de archivos, una lista de hosts, una lista de usuarios, una lista de URL o una lista de tablas. Un trabajo también puede ser un comando que lee desde una tubería. GNU paralelo puede luego dividir la entrada en bloques y canalizar un bloque en cada comando en paralelo.

Si usa xargs y tee hoy, encontrará que GNU paralelo es muy fácil de usar ya que GNU paralelo está escrito para tener las mismas opciones que xargs. Si escribe bucles en Shell, encontrará que GNU paralelo puede reemplazar la mayoría de los bucles y hacerlos ejecutar más rápido ejecutando varios trabajos en paralelo.

GNU paralelo se asegura de que la salida de los comandos sea la misma que obtendría si ejecutara los comandos secuencialmente. Esto hace posible utilizar la salida de GNU paralelo como entrada para otros programas.

Respuesta3

findNo haré eso por ti.

cree un script, ubique sus scripts for_loop.sh y ejecútelos, así:

#!/bin/bash

for theScript in $(find dir_* -name for_loop.sh); do
  "$theScript" &
done

Si el script debe ejecutarse dentro del subdirectorio, intente cdhacerlo antes, tal vez como cd $(dirname "$theScript") && . $(basename "$theScript").

Mis ejemplos no se prueban en detalle y no son tolerantes a errores...

Edición 1:

ComoSato Katsuracomentado correctamente, el script anterior se interrumpe si hay espacios en el nombre del directorio.

Entonces cambié para hacer un bucle a read:

#!/bin/bash
find dir_* -name for_loop.sh | while IFS= read -r theScript; do
  "$theScript" &
done

Respuesta4

puedes hacerlo desde tu directorio de nivel superior

for D in `find . -type d -maxdepth 1`
do 
     $D/<yourScriptName>.sh &
done

el "&" es para ejecutarlos en segundo plano

información relacionada