Мне не нравится использовать wait
, потому что он блокируется до завершения процесса, что не идеально, если есть несколько процессов, ожидающих, так как я не могу получить обновление статуса до завершения текущего процесса. Я предпочитаю использовать комбинацию kill -0
и sleep
для этого.
Учитывая массив pids
для ожидания, я использую приведенную ниже функцию waitPids()
, чтобы получить непрерывную обратную связь о том, какие пиды еще ожидают завершения.
declare -a pids
waitPids() {
while [ ${#pids[@]} -ne 0 ]; do
echo "Waiting for pids: ${pids[@]}"
local range=$(eval echo {0..$((${#pids[@]}-1))})
local i
for i in $range; do
if ! kill -0 ${pids[$i]} 2> /dev/null; then
echo "Done -- ${pids[$i]}"
unset pids[$i]
fi
done
pids=("${pids[@]}") # Expunge nulls created by unset.
sleep 1
done
echo "Done!"
}
Когда я запускаю процесс в фоновом режиме, я немедленно добавляю его pid в массив pids
, используя следующую служебную функцию:
addPid() {
desc=$1
pid=$2
echo "$desc -- $pid"
pids=(${pids[@]} $pid)
}
Вот пример, который показывает, как использовать:
for i in {2..5}; do
sleep $i &
addPid "Sleep for $i" $!
done
waitPids
А вот как выглядит обратная связь:
Sleep for 2 -- 36271
Sleep for 3 -- 36272
Sleep for 4 -- 36273
Sleep for 5 -- 36274
Waiting for pids: 36271 36272 36273 36274
Waiting for pids: 36271 36272 36273 36274
Waiting for pids: 36271 36272 36273 36274
Done -- 36271
Waiting for pids: 36272 36273 36274
Done -- 36272
Waiting for pids: 36273 36274
Done -- 36273
Waiting for pids: 36274
Done -- 36274
Done!