
Я пытаюсь создать скрипт оболочки для запуска серии долгоиграющих процессов. Назовем их a, b, c, d и e. Процессы b, c и d должны работать параллельно, а процесс e должен работать после того, как все предыдущие будут завершены.успешно.
Вот мой (псевдо-)код:
{
echo "starting a"
a
}&&
{
(echo "starting b"; b; exit $?)&
(echo "starting c"; c; exit $?)&
(echo "starting d"; d; exit $?)&
wait
}&&
{
echo "starting e"
e
}
Моя проблема в том, что если какой-либо из пунктов b, c, d не выполняется, скрипт продолжается и выполняется пункт e. Есть ли способ предотвратить это?
Огромное спасибо за любые ответы!
Антуан
решение1
{
(echo "starting b"; b)&
(echo "starting c"; c)&
(echo "starting d"; d)&
wait %1 && wait %2 && wait %3
}&&
при ожидании определенного задания wait
возвращается код выхода этого задания
Чтобы понять, посмотрите на эти два примера:
Важна только последняя строка (показывает статус выхода wait
)
(sleep 3; false) & wait; echo $?
[1] 25358
[1]+ Exit 1 ( sleep 3; false )
0
--
(sleep 3; false) & wait %1; echo $?
[1] 25362
[1]+ Exit 1 ( sleep 3; false )
1
решение2
Запустив процесс в фоновом режиме, вы по сути сообщаете оболочке, что вас не интересует его успех или неудача.
wait
волясообщать значение любого сигнала в его выходном коде, если это применимо. Это не то, что вы ищете.
Решением было бы заставить каждую команду сообщать о своем статусе в stdout и подсчитывать ответы с помощью grep.
{
(echo "starting b"; b && echo ok)&
(echo "starting c"; c && echo ok)&
(echo "starting d"; d && echo ok)&
} |
grep -c ok | ( read n && (( n==3 )) ) &&
{
echo "starting e"; e
}