Rsync cronjob, который будет работать, только если rsync еще не запущен - PullRequest
20 голосов
/ 22 февраля 2012

Я проверил решение здесь, но не могу найти его. Я имею дело с очень медленным WAN-соединением около 300 Кбит / с. Для своих загрузок я использую удаленный ящик, а затем загружаю их в свой дом. Я пытаюсь запустить cronjob, который будет rsync два каталога на моем удаленном и локальном сервере каждый час. У меня все работает, но если есть много данных для передачи перекрытия rsyncs и в итоге создается два экземпляра одного и того же файла, таким образом дублируются отправленные данные.

Я хочу вместо этого вызвать скрипт, который будет запускать мою команду rsync, но только если rsync не запущен?

Ответы [ 4 ]

80 голосов
/ 02 апреля 2012

Проблема с созданием файла «блокировки», как предлагалось в предыдущем решении, заключается в том, что файл блокировки может уже существовать, если скрипт, ответственный за его удаление, завершается ненормально.Это может произойти, например, если пользователь завершает процесс rsync или из-за сбоя питания.Вместо этого следует использовать <a href="http://linux.die.net/man/1/flock" rel="noreferrer">flock</a>, который не страдает от этой проблемы.

Поскольку это происходит, flock также прост в использовании, поэтому решение будет выглядеть просто так:

flock -n lock_file -c "rsync ..."

Команда после опции -c выполняется только в том случае, если в файле lock_file нет другой блокировки процесса.Если процесс блокировки по какой-либо причине завершается, блокировка будет снята с файла lock_file.Опции -n говорят, что flock должен быть неблокирующим, поэтому, если есть другие процессы, блокирующие файл, ничего не произойдет.

8 голосов
/ 22 февраля 2012

С помощью скрипта вы можете создать файл блокировки.Если файл существует, cronjob должен пропустить прогон;иначе это должно продолжаться.После завершения сценария он должен удалить файл блокировки.

if [ -e /home/myhomedir/rsyncjob.lock ]
then
  echo "Rsync job already running...exiting"
  exit
fi

touch /home/myhomedir/rsyncjob.lock

#your code in here

#delete lock file at end of your job

rm /home/myhomedir/rsyncjob.lock
5 голосов
/ 10 августа 2015

Простое решение без использования файла блокировки заключается в следующем:

pgrep rsync > /dev/null || rsync -avz ...

Это будет работать до тех пор, пока это единственное задание rsync, которое вы запускаете на сервере, и вы можете запустить его непосредственно в cron, но вам нужно будет перенаправить вывод в файл журнала.

Если вы выполняете несколько заданий rsync, вы можете заставить pgrep сопоставлять полную командную строку с шаблоном, подобным следующему:

pgrep -f rsync.*/data > /dev/null || rsync -avz --delete /data/ otherhost:/data/
pgrep -f rsync.*/www  > /dev/null || rsync -avz --delete /var/www/ otherhost:/var/www/
2 голосов
/ 21 мая 2016

Чтобы использовать пример файла блокировки, указанный @User выше, необходимо использовать ловушку для проверки того, что файл блокировки удален при выходе из сценария по любой причине.

if [ -e /home/myhomedir/rsyncjob.lock ]
then
  echo "Rsync job already running...exiting"
  exit
fi

touch /home/myhomedir/rsyncjob.lock

#delete lock file at end of your job

trap 'rm /home/myhomedir/rsyncjob.lock' EXIT

#your code in here

Таким образом, блокировкафайл будет удален, даже если сценарий завершится до его окончания.

...