Il pid di un processo figlio in background è memorizzato in $! . È possibile memorizzare i pid di tutti i processi figli in un array, ad esempio PIDS [] .
wait [-n] [jobspec or pid …]
Attendere finché il processo figlio specificato da ciascun ID processo pid o specifica lavoro jobspec non esce e restituisce lo stato di uscita dell'ultimo comando atteso. Se viene fornita una specifica di lavoro, vengono attesi tutti i processi nel lavoro. Se non vengono forniti argomenti, vengono attesi tutti i processi figli attualmente attivi e lo stato di ritorno è zero. Se viene fornita l'opzione -n, wait attende che qualsiasi lavoro termini e restituisce il suo stato di uscita. Se né jobspec né pid specificano un processo figlio attivo della shell, lo stato di ritorno è 127.
Usa il comando wait puoi aspettare che tutti i processi figli finiscano, nel frattempo puoi ottenere lo stato di uscita di ogni processo figlio tramite $? e memorizzare lo stato in STATUS [] . Quindi puoi fare qualcosa a seconda dello stato.
Ho provato le seguenti 2 soluzioni e funzionano bene. solution01 è più conciso, mentre solution02 è un po 'complicato.
solution01
#!/bin/bash
# start 3 child processes concurrently, and store each pid into array PIDS[].
process=(a.sh b.sh c.sh)
for app in ${process[@]}; do
./${app} &
PIDS+=($!)
done
# wait for all processes to finish, and store each process's exit code into array STATUS[].
for pid in ${PIDS[@]}; do
echo "pid=${pid}"
wait ${pid}
STATUS+=($?)
done
# after all processed finish, check their exit codes in STATUS[].
i=0
for st in ${STATUS[@]}; do
if [[ ${st} -ne 0 ]]; then
echo "$i failed"
else
echo "$i finish"
fi
((i+=1))
done
solution02
#!/bin/bash
# start 3 child processes concurrently, and store each pid into array PIDS[].
i=0
process=(a.sh b.sh c.sh)
for app in ${process[@]}; do
./${app} &
pid=$!
PIDS[$i]=${pid}
((i+=1))
done
# wait for all processes to finish, and store each process's exit code into array STATUS[].
i=0
for pid in ${PIDS[@]}; do
echo "pid=${pid}"
wait ${pid}
STATUS[$i]=$?
((i+=1))
done
# after all processed finish, check their exit codes in STATUS[].
i=0
for st in ${STATUS[@]}; do
if [[ ${st} -ne 0 ]]; then
echo "$i failed"
else
echo "$i finish"
fi
((i+=1))
done