O pid de um processo filho em segundo plano é armazenado em $! . Você pode armazenar todos os pids dos processos filhos em uma matriz, por exemplo, PIDS [] .
wait [-n] [jobspec or pid …]
Aguarde até que o processo filho especificado por cada ID de processo pid ou especificação de tarefa jobspec saia e retorne o status de saída do último comando esperado. Se uma especificação de trabalho for fornecida, todos os processos no trabalho serão aguardados. Se nenhum argumento for fornecido, todos os processos filhos ativos no momento serão aguardados e o status de retorno será zero. Se a opção -n for fornecida, aguarde o término de qualquer trabalho e retorne seu status de saída. Se nem jobspec nem pid especificarem um processo filho ativo do shell, o status de retorno será 127.
Use o comando wait, você pode esperar pelo término de todos os processos filhos, enquanto isso, você pode obter o status de saída de cada processo filho via $? e armazene o status no STATUS [] . Então você pode fazer algo dependendo do status.
Eu tentei as 2 soluções a seguir e elas funcionam bem. solution01 é mais conciso, enquanto solution02 é um pouco complicado.
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