¿Cómo esperar en bash a que finalicen varios subprocesos y devolver el código de salida! = 0 cuando cualquier subproceso finaliza con el código! = 0?

Resuelto tkokoszka asked hace 15 años • 35 respuestas

¿Cómo esperar en un script bash a que finalicen varios subprocesos generados a partir de ese script y luego devolver el código de salida !=0cuando cualquiera de los subprocesos finaliza con el código !=0?

Guión sencillo:

#!/bin/bash
for i in `seq 0 9`; do
  doCalculations $i &
done
wait

El script anterior esperará los 10 subprocesos generados, pero siempre dará el estado de salida 0(ver help wait). ¿Cómo puedo modificar este script para que descubra los estados de salida de los subprocesos generados y devuelva el código de salida 1cuando cualquiera de los subprocesos finalice con código !=0?

¿Existe alguna solución mejor para eso que recopilar los PID de los subprocesos, esperarlos en orden y sumar los estados de salida?

tkokoszka avatar Dec 10 '08 20:12 tkokoszka
Aceptado

waittambién (opcionalmente) toma el PIDproceso a esperar y $!obtiene el PIDúltimo comando iniciado en segundo plano. Modifique el bucle para almacenar PIDcada subproceso generado en una matriz y luego vuelva a realizar el bucle esperando cada uno PID.

# run processes and store pids in array
for i in $n_procs; do
    ./procs[${i}] &
    pids[${i}]=$!
done

# wait for all pids
for pid in ${pids[*]}; do
    wait $pid
done
Luca Tettamanti avatar Dec 10 '2008 14:12 Luca Tettamanti

http://jeremy.zawodny.com/blog/archives/010717.html :

#!/bin/bash

FAIL=0

echo "starting"

./sleeper 2 0 &
./sleeper 2 1 &
./sleeper 3 0 &
./sleeper 2 0 &

for job in `jobs -p`
do
echo $job
    wait $job || let "FAIL+=1"
done

echo $FAIL

if [ "$FAIL" == "0" ];
then
echo "YAY!"
else
echo "FAIL! ($FAIL)"
fi
HoverHell avatar Feb 05 '2009 09:02 HoverHell

Aquí hay un ejemplo simple usando wait.

Ejecute algunos procesos:

$ sleep 10 &
$ sleep 10 &
$ sleep 20 &
$ sleep 20 &

Luego espéralos con waitel comando:

$ wait < <(jobs -p)

O simplemente wait(sin argumentos) para todos.

Esto esperará a que se completen todos los trabajos en segundo plano.

Si -nse proporciona la opción, espera a que finalice el siguiente trabajo y devuelve su estado de salida.

Ver: help waity help jobspara la sintaxis.

Sin embargo, la desventaja es que esto devolverá solo el estado del último ID, por lo que debe verificar el estado de cada subproceso y almacenarlo en la variable.

O haga que su cálculo funcione para crear algún archivo en caso de falla (vacío o con registro de fallas), luego verifique ese archivo si existe, por ejemplo

$ sleep 20 && true || tee fail &
$ sleep 20 && false || tee fail &
$ wait < <(jobs -p)
$ test -f fail && echo Calculation failed.
kenorb avatar Mar 16 '2016 14:03 kenorb