"UNIX", сложная вещь - в основном, в FreeBSD не может быть сказано, что это - Unix, потому что Unix регистрируется как торговую марку, и у них нет соответствующей лицензии. Это также не получено на основании кода System V, который является направлением, которое взяли основные источники Unix.
Некоторые старые версии Unix действительно теперь имеют исходный код в наличии - особенно Версия 7 Unix, одна из последних версий PDP-11. Дерево Unix имеет доступный для просмотра исходный код для V7 и нескольких других дистрибутивов Unix.
Можно сделать это при помощи временного каталога.
# Create a temporary directory to store the statuses
dir=$(mktemp -d)
# Execute the backgrouded code. Create a file that contains the exit status.
# The filename is the PID of this group's subshell.
for i in 1 2; do
{ ssh mysql "/root/test$i.sh" ; echo "$?" > "$dir/$BASHPID" ; } &
done
# Wait for all jobs to complete
wait
# Get return information for each pid
for file in "$dir"/*; do
printf 'PID %d returned %d\n' "${file##*/}" "$(<"$file")"
done
# Remove the temporary directory
rm -r "$dir"
Проблема больше с Вашим
for i in ${#pid[@]}
Который является for i in 2
.
Это должно скорее быть:
for i in 1 2
или
for ((i = 1; i <= ${#pid[@]}; i++))
wait "$pid"
возвратит код выхода задания с bash
(и оболочки POSIX, но нет zsh
) даже если задание уже завершилось когда wait
был запущен.
Ответ Stéphane хорош, но я бы предпочел
for i in ${!pid[@]}
do
wait ${pid[i]}
return[i]=$?
unset "pid[$i]"
done
, который будет итерации на клавиши массива PID
, независимо от того, какие записи все еще существуют, поэтому вы можете адаптировать его, вырваться из цикла И повторно запустите весь цикл, и это просто будет работать. И вам не нужно последовательные значения I
, чтобы начать с.
Конечно, если вы имеете дело с тысячами процессов, возможно, пожалуй, подход StePane будет более эффективным, когда у вас есть неэнстрационный список.
Общая реализация без временных файлов.
#!/usr/bin/env bash
## associative array for job status
declare -A JOBS
## run command in the background
background() {
eval $1 & JOBS[$!]="$1"
}
## check exit status of each job
## preserve exit status in ${JOBS}
## returns 1 if any job failed
reap() {
local cmd
local status=0
for pid in ${!JOBS[@]}; do
cmd=${JOBS[${pid}]}
wait ${pid} ; JOBS[${pid}]=$?
if [[ ${JOBS[${pid}]} -ne 0 ]]; then
status=${JOBS[${pid}]}
echo -e "[${pid}] Exited with status: ${status}\n${cmd}"
fi
done
return ${status}
}
background 'sleep 1 ; false'
background 'sleep 3 ; true'
background 'sleep 2 ; exit 5'
background 'sleep 5 ; true'
reap || echo "Ooops! Some jobs failed"