es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Bash espera a que todos los procesos terminen (no funciona)

Tengo un directorio con varios subdirectorios con los nombres:

1
2
3
4
backup_1
backup_2

Escribí un código bash con paralelización para procesar archivos en estas carpetas y un ejemplo mínimo de trabajo es el siguiente:

!/bin/bash

P=pwd
task(){
    dirname=$(basename $dir)
    echo $dirname running >> output.out
    if [[ $dirname != "backup"* ]]; then
        sed -i "s/$dirname running/$dirname is good/" $P/output.out
    else
        sed -i "s/$dirname running/$dirname ignored/" $P/output.out
    fi
}

for dir in */; do
    ((i=i%8)); ((i++==0)) && wait
    task "$dir" &
done
wait
echo all done

La función “wait” al final del script debería esperar a que todos los procesos terminen antes de continuar con echo “all done”. El archivo output.out, después de que todos los procesos terminen debería mostrar:

1 is good
2 is good
3 is good
4 is good
backup1 ignored
backup2 ignored

Soy capaz de obtener esta salida si configuro el script para que se ejecute en serie con ((i=i%1)); ((i++==0)) && wait. Sin embargo, si lo ejecuto en paralelo con ((i=i%2)); ((i++==0)) && wait, obtengo algo como:

2 is good
1 running
3 running
4 is good
backup1 running
backup2 ignored

¿Alguien puede decirme por qué wait no funciona en este caso?

También sé que GNU parallel puede hacer lo mismo al paralelizar tareas. Sin embargo, no sé cómo comandar a parallel para que ejecute esta tarea en todos los subdirectorios en el directorio principal. Sería genial si alguien pudiera producir un script de muestra que pueda seguir.

Muchas gracias
Jacek

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece ser que el problema con su script es que el comando wait no está siendo ejecutado hasta después del comando echo all done. Esto significa que el comando wait no está esperando a que todos los procesos terminen antes de que sea ejecutado. Para solucionar esto, debe mover el comando wait al final del bucle, antes del comando echo all done.

    En cuanto a usar GNU Parallel para ejecutar esta tarea en todos los sub-directorios del directorio padre, puede usar el siguiente comando:

    parallel --jobs 8 --results output.out 'task {}' ::: */
    

    Esto ejecutará el comando task en todos los sub-directorios del directorio padre en paralelo, con un máximo de 8 trabajos ejecutándose al mismo tiempo. Los resultados se almacenarán en el archivo output.out.

Comments are closed.