여기 파티에 정말 늦었지만 여기에 또 다른 해결책이 있습니다.
많은 솔루션이 명령에서 공백 / 특수 문자를 처리하지 않거나, 항상 N 개의 작업을 실행하지 않거나, 바쁜 루프에서 CPU를 먹거나, 외부 종속성 (예 : GNU parallel) 에 의존하지 않습니다 .
함께 죽은 / 좀비 프로세스 처리를위한 영감 , 여기에 순수 bash는 솔루션입니다 :
function run_parallel_jobs {
local concurrent_max=$1
local callback=$2
local cmds=("${@:3}")
local jobs=( )
while [[ "${#cmds[@]}" -gt 0 ]] || [[ "${#jobs[@]}" -gt 0 ]]; do
while [[ "${#jobs[@]}" -lt $concurrent_max ]] && [[ "${#cmds[@]}" -gt 0 ]]; do
local cmd="${cmds[0]}"
cmds=("${cmds[@]:1}")
bash -c "$cmd" &
jobs+=($!)
done
local job="${jobs[0]}"
jobs=("${jobs[@]:1}")
local state="$(ps -p $job -o state= 2>/dev/null)"
if [[ "$state" == "D" ]] || [[ "$state" == "Z" ]]; then
$callback $job
else
wait $job
$callback $job $?
fi
done
}
그리고 샘플 사용법 :
function job_done {
if [[ $# -lt 2 ]]; then
echo "PID $1 died unexpectedly"
else
echo "PID $1 exited $2"
fi
}
cmds=( \
"echo 1; sleep 1; exit 1" \
"echo 2; sleep 2; exit 2" \
"echo 3; sleep 3; exit 3" \
"echo 4; sleep 4; exit 4" \
"echo 5; sleep 5; exit 5" \
)
cpus=3
run_parallel_jobs $cpus "job_done" "${cmds[@]}"
출력 :
1
2
3
PID 56712 exited 1
4
PID 56713 exited 2
5
PID 56714 exited 3
PID 56720 exited 4
PID 56724 exited 5
프로세스 별 출력 처리를 $$사용하여 파일에 기록 할 수 있습니다. 예를 들면 다음과 같습니다.
function job_done {
cat "$1.log"
}
cmds=( \
"echo 1 \$\$ >\$\$.log" \
"echo 2 \$\$ >\$\$.log" \
)
run_parallel_jobs 2 "job_done" "${cmds[@]}"
산출:
1 56871
2 56872