Есть ли способ остановить сценарии, которые выполняются одновременно, если один из них посылает эхо? - PullRequest
0 голосов
/ 24 июня 2019

Мне нужно найти значение (на самом деле оно более сложное) на одном из 20 серверов, которые у меня есть.И мне нужно сделать это как можно быстрее.Прямо сейчас я отправляю сценарии одновременно на все серверы.Мой основной сценарий выглядит примерно так (но со всеми серверами):

#!/bin/sh
#mainScript.sh
value=$1

c1=`cat serverList | sed -n '1p'`
c2=`cat serverList | sed -n '2p'`

sh find.sh $value $c1 & sh find.sh $value $c2


#!/bin/sh
#find.sh

#some code here .....


if [ $? -eq 0 ]; then
  rm $tempfile
else

myValue=`sed -n '/VALUE/p' $tempfile | awk 'BEGIN{FS="="} {print substr($2, 8, length($2)-2)}'`
echo "$myValue"
fi

Таким образом, сценарий возвращает ответ, только если находит значение на сервере.Я хотел бы знать, есть ли способ прекратить выполнение других сценариев, если один из них уже возвращает значение.

Я попытался добавить «выход» в сценарий find.sh, но он не остановитсявсе сценарии.Может кто-нибудь сказать мне, возможно ли то, что я хочу сделать?

Ответы [ 2 ]

1 голос
/ 25 июня 2019

Я бы посоветовал вам использовать что-то, что может с этим справиться: GNU Parallel . Из связанного урока:

Если вы ищете успех, а не неудачи, вы можете использовать успех. Это закончится, как только первая работа будет успешной:

parallel -j2 --halt now,success=1 echo {}\; exit {} ::: 1 2 3 0 4 5 6

Выход:

  1
  2
  3
  0
  parallel: This job succeeded:
  echo 0; exit 0
0 голосов
/ 24 июня 2019

Я предлагаю вам начать с изменения find.sh, чтобы его код возврата зависел от его успешности, что позволит нам легче определить успешный вызов;например:

myValue=`sed -n '/VALUE/p' $tempfile | awk 'BEGIN{FS="="} {print substr($2, 8, length($2)-2)}'`
success=$?
echo "$myValue"
exit $success

Чтобы завершить все процессы find.sh, порожденные вашим сценарием, вы можете использовать pkill с критериями ID родительского процесса и критериями имени команды:

pkill -P $$ find.sh # $$ refers to the current process' PID

Обратите внимание, что для этого требуется, чтобы вы запускали скрипт find.sh напрямую, а не передавали его в качестве параметра sh.Обычно это не должно быть проблемой, но если у вас есть веская причина для вызова sh вместо сценария, вы можете заменить find.sh в команде pkill на sh (при условии, что вы не порождаете другихскрипты, которые вы не хотели бы убивать).

Теперь, когда find.sh завершается с успехом только тогда, когда он находит ожидаемую строку, вы можете подключить два действия с помощью && и запустить все это в фоновом режиме:

{ find.sh $value $c1 && pkill -P $$ find.sh; } &

Первое вхождение find.sh, которое завершается успешно, вызовет команду pkill, которая завершит все остальные (эти уничтоженные процессы будут иметь ненулевые коды выхода и поэтому не будут запускать своисвязанный pkill).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...