Хоча зробити це правильно bash, можливо, неможливо, ви можете зробити напівправо досить легко. bstarkдав справедливе наближення права, але у нього є такі недоліки:
- Розбиття слів: Ви не можете передати йому жодне завдання, яке використовує будь-який із наступних символів у своїх аргументах: пробіли, вкладки, нові рядки, зірочки, знаки запитання. Якщо ви це зробите, справи зламаються, можливо, несподівано.
- Він покладається на решту вашого сценарію, щоб нічого не фонувати. Якщо ви це зробите, або пізніше ви додасте до сценарію щось, що надсилається у фоновому режимі, тому що ви забули, що вам не дозволено використовувати фонові завдання через його фрагмент, справи зламаються.
Іншим наближенням, яке не має цих недоліків, є наступне:
scheduleAll() {
local job i=0 max=4 pids=()
for job; do
(( ++i % max == 0 )) && {
wait "${pids[@]}"
pids=()
}
bash -c "$job" & pids+=("$!")
done
wait "${pids[@]}"
}
Зауважте, що цей варіант легко адаптувати, а також перевірити код виходу кожного завдання, коли він закінчується, щоб ви могли попередити користувача, якщо завдання не вдається, або встановити код виходу scheduleAllвідповідно до кількості невдалих завдань або чогось іншого.
Проблема цього коду полягає якраз у тому, що:
- Він планує одночасно чотири (у цьому випадку) завдання, а потім чекає закінчення всіх чотирьох. Деякі з них можуть бути зроблені раніше, ніж інші, що призведе до того, що наступна партія з чотирьох завдань зачекає, поки не буде виконано найдовший з попередньої партії.
Рішення, яке піклується про останню проблему, потрібно було б використати, kill -0щоб опитати, чи не зник який-небудь із процесів, а не waitзапланувати наступне завдання. Однак це вводить невелику нову проблему: у вас є перегони між закінченням роботи та kill -0перевіркою, чи закінчилося воно. Якщо робота закінчилася, і одночасно у вашій системі запускається інший процес, беручи випадковий ПІД, який випадково відповідає роботі, яка щойно закінчилась, kill -0ви не помітите, що ваша робота закінчилася, і все знову зламається.
Ідеальне рішення неможливе у bash.