Как запустить несколько процессов и выхода, если кто-либо из них выходит или не удается

rsync -avr  --delete-excluded --include=*.txt /source /* /destination 

Может помочь вам. Дай мне знать.

5
11.12.2018, 10:14
2 ответа

Это болезненно в оболочках, потому что встроенная функция waitне выполняет «ожидание любого», она выполняет «ожидание всех». waitбез аргумента ожидает выхода всех дочерних процессов и возвращает 0. waitс явным списком процессов ждет выхода всех из них и возвращает статус последнего аргумента. Чтобы дождаться нескольких потомков и получить их статус выхода, вам нужен другой подход. waitможет дать вам статус выхода, только если вы знаете, какой ребенок уже мертв.

Одним из возможных подходов является использование выделенного именованного канала для сообщения о состоянии каждого дочернего элемента. Следующий фрагмент (не проверен! )возвращает наибольший из дочерних состояний.

mkfifo status_pipe
children=0
{ child1; echo 1 $? >status_pipe; } & children=$((children+1))
{ child2; echo 2 $? >status_pipe; } & children=$((children+1))
max_status=0
while [ $children -ne 0 ]; do
  read -r child status <status_pipe
  children=$((children-1))
  if [ $status -gt $max_status ]; then
    max_status=$status
  fi
done
rm status_pipe

Обратите внимание, что это будет заблокировано навсегда, если одна из подоболочек умрет, не сообщив о своем статусе. В типичных условиях этого не произойдет, но это может произойти, если подоболочка была убита вручную или если подоболочке не хватило памяти.

Если вы хотите что-то сделать, как только один из потомков выйдет из строя, замените if [ $status -gt $max_status ]; then …на if [ $status -ne 0 ]; then ….

2
27.01.2020, 20:40

GNU Parallel имеет --halt. Он убьет все запущенные задания, если одно из заданий завершится или умрет, и вернет false, если задание не выполнено :

.
parallel --halt now,done=1 ::: 'sleep 1;echo a' 'sleep 2;echo b' ||
  echo the job that finished failed

parallel --halt now,done=1 ::: 'sleep 1;echo a;false' 'sleep 2;echo b' ||
  echo the job that finished failed

Для систем, в которых не установлен GNU Parallel, вы обычно можете написать свой скрипт в системе, на которой установлена ​​GNU Parallel, и использовать --embedдля встраивания GNU Parallel непосредственно в скрипт:

parallel --embed > myscript.sh
3
27.01.2020, 20:40

Теги

Похожие вопросы