Параллельное выполнение скрипта

Программирование на sh, быть может немного про альтернативные языки
Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
densan
ст. сержант
Сообщения: 370
Зарегистрирован: 2007-12-06 10:02:02
Откуда: Penza
Контактная информация:

Параллельное выполнение скрипта

Непрочитанное сообщение densan » 2013-05-14 12:16:09

Здравствуйте.
Сделал скрипт, который делает синхронизацию с помощью rsync пользовательских профилей из удаленных офисов на сервер в центральном офисе для последующего архивирования. Данные о сервере, каталоге куда писать и скорости канала этот скрипт берет из дополнительного файла:

Код: Выделить всё

 cat servers
server1 cp 1000
server2 sr 4
server3 ar 2
...
...
Но скрипт выполняет команды последовательно для всех серверов: вначале первый сервер, потом второй ... . Процедура синхронизации - длительная и при последовательном варианте синхронизации за ночь не успевает.
Подскажите как организовать, чтобы скрипт запускал процедуру синхронизации и не дожидался ее окончания.

Код: Выделить всё

#!/bin/sh
#
log="/var/log/rsync/rsync-all.log"
config="/usr/local/etc/rsyncd/servers"
echo="/bin/echo"
date="/bin/date"
grep="/usr/bin/grep"
ping="/sbin/ping"
rsync="/usr/local/bin/rsync"
rootdir="/data/stripe/backup"
mkdir="/bin/mkdir"
touch="/usr/bin/touch"

while read server dir bw
do
   $echo "===================================================================" >> $log
#проверяем доступность IP сервера по пингу
   $ping -q -c 4 $server > /dev/null 2>&1
   if [ $? -eq 0 ]; then
        $echo "`$date +%F_%H-%M-%S`  Server $server ping=OK" >> $log
   else
        $echo "`$date +%F_%H-%M-%S`  Server $server down" >> $log
        exit 0;
   fi
   $echo "===================================================================" >> $log
#создаем каталог куда будет писать rsync
   k="$rootdir/$dir/profiles"
   $mkdir -p $k
#создаем файл лога
   $touch /var/log/rsync/rsync-$dir.log
#высчитываем лимит скорости для rsync, оставляем 20KBs для остального трафика
   let b=$bw*128-20
   $echo "Start Rsync on speed $b">> $log
   s="$rsync --archive --exclude-from=/usr/local/etc/rsyncd/exclude.txt --bwlimit=$b  --chmod=ugo=rwx --compress-level=9 --delete-after  --recursive --log-file=/var/log/rsync/rsync-$dir.log --8-bit-output  $server::profiles $k"
   $echo "команда старта $s">> $log
   $s
   done < $config

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

kpp
лейтенант
Сообщения: 613
Зарегистрирован: 2009-08-05 16:10:46
Откуда: Украина Днепропетровск-Киев
Контактная информация:

Re: Параллельное выполнение скрипта

Непрочитанное сообщение kpp » 2013-05-14 16:51:56

Общая структура:

Код: Выделить всё

#!/bin/sh
#
...

script_name="SCRIPT.SH"
# кол-во одновременно запущенных экземпляров скрипта SCRIPT.SH
max_kolvo=3
time_wait=10


check_execut()
{
 ps -x | grep ${1} | grep -v grep | sed 's/^[^ >]*[ <-->]*[^ <->]*[ <-->]*[^ <->]*[ <-->]*[^ <->]*[ <-->]*\(.*\)$/\1/' |\
  sort -u | wc -l | sed 's/^[ <>]*//'
 return 0
}


 while read server dir bw
 do
     while true
     do
         kol=`check_execut ${script_name}`
         [ ${kol} -lt ${max_kolvo} ] && {
             sh ${script_name} НЕОБХОДИМЫЕ ПАРАМЕТРЫ  >> log 2>&1 &
             break
         }
         sleep ${time_wait}
     done
 done < $config

 # ожидать окончания выполнения всех экземпляров SCRIPT.SH
while true
do
     kol=`check_execut ${script_name}`
     [ ${kol} -eq 0 ] && break
     sleep ${time_wait}
done
...
В SCRIPT.SH - код, который выполняется для каждой итерации, т.е. те полезные действия которые нужно выполнить.
check_execut - функция, определяющая кол-во запущенных экземпляров скрипта SCRIPT.SH
Нет, ребята, я не гордый. Не загадывая вдаль, так скажу: зачем мне орден? Я согласен на медаль.

kpp
лейтенант
Сообщения: 613
Зарегистрирован: 2009-08-05 16:10:46
Откуда: Украина Днепропетровск-Киев
Контактная информация:

Re: Параллельное выполнение скрипта

Непрочитанное сообщение kpp » 2013-05-14 17:06:28

В отдельный файл-скрипт (SCRIPT.SH) помещаем все, что в вашем варианте в теле цикла.
Определяем входные параметры для этого скрипта.
Функция check_execut() работает во Фре.
<-->, <>, > в этой ф-ции - символы табуляции.
Нет, ребята, я не гордый. Не загадывая вдаль, так скажу: зачем мне орден? Я согласен на медаль.

densan
ст. сержант
Сообщения: 370
Зарегистрирован: 2007-12-06 10:02:02
Откуда: Penza
Контактная информация:

Re: Параллельное выполнение скрипта

Непрочитанное сообщение densan » 2013-05-15 18:41:35

Спасибо за помощь.

kpp
лейтенант
Сообщения: 613
Зарегистрирован: 2009-08-05 16:10:46
Откуда: Украина Днепропетровск-Киев
Контактная информация:

Re: Параллельное выполнение скрипта

Непрочитанное сообщение kpp » 2013-05-23 17:10:02

Судя по кол-во просмотров этой темы (за 8 дней 800 просмотров), многих волновал этот вопрос, но стеснялись спросить :oops: :-D
Нет, ребята, я не гордый. Не загадывая вдаль, так скажу: зачем мне орден? Я согласен на медаль.