Скрипт резервного копирования требует блокировки pid для предотвращения нескольких экземпляров
У меня есть сценарий Bash, который выполняет ежедневные инкрементные резервные копии rsync.
моя проблема в том, что я в конечном итоге работает несколько экземпляров. Я новичок в скриптах Bash, так что я не уверен, если у меня есть проблема в моем скрипте? размещено ниже.
но я читал о pid lockfile?
Кто-нибудь может показать мне, как я могу добавить это в мой сценарий?
#!/bin/bash
PATH=/usr/lib64/qt- 3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
LinkDest=/home/backup/files/backupdaily/monday
WeekDay=$(date +%A |tr [A-Z] [a-z])
echo "$WeekDay"
case $WeekDay in
monday)
echo "Starting monday's backup"
rsync -avz --delete --exclude backup --exclude virtual_machines /home /home/backup/files/backupdaily/monday --log- file=/usr/local/src/backup/logs/backup_daily.log
;;
tuesday|wednesday|thursday|friday|saturday)
echo "Starting inc backup : $WeekDay"
rsync -avz --exclude backup --exclude virtual_machines --link-dest=$LinkDest /home /home/backup/files/backupdaily/$WeekDay --log- file=/usr/local/src/backup/logs/backup_daily.log
;;
sunday) exit 0
;;
esac
так это выглядит так?
#!/bin/bash
PATH=/usr/lib64/qt- 3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
trap "rm -f /tmp/backup_daily_lockfile && exit" SIGINT SIGTERM #Put this on the top to handle CTRL+C or SIGTERM
test -f /tmp/backup_daily_lockfile && exit #before rsync to ensure that the script will not run if there is another one running
LinkDest=/home/backup/files/backupdaily/monday
WeekDay=$(date +%A |tr [A-Z] [a-z])
echo "$WeekDay"
touch /tmp/backup_daily_lockfile #Before the rsync
case $WeekDay in
monday)
echo "Starting monday's backup"
rsync -avz --delete --exclude backup --exclude virtual_machines /home /home/backup/files/backupdaily/monday --log-file=/usr/local/src/backup/logs/backup_daily.log
;;
tuesday|wednesday|thursday|friday|saturday)
echo "Starting inc backup : $WeekDay"
rsync -avz --exclude backup --exclude virtual_machines --link-dest=$LinkDest /home /home/backup/files/backupdaily/$WeekDay --log-file=/usr/local/src/backup/logs/backup_daily.log
;;
sunday) exit 0
;;
rm -f /tmp/backup_daily_lockfile #After the rsync
esac
2 ответа
Добавьте следующее в ваш скрипт:
trap "rm -f /tmp/lockfile && exit" SIGINT SIGTERM #Put this on the top to handle CTRL+C or SIGTERM
test -f /tmp/lockfile && exit #Before rsync to ensure that the script will not run if there is another one running
touch /tmp/lockfile #Before the rsync
rm -f /tmp/lockfile #After the rsync
переименуйте путь / имя файла блокировки в соответствии с вашими потребностями, вы также можете назвать его с текущим PID, используя переменную $$.
У вашего предложенного решения есть условие гонки. Если два экземпляра работают примерно в одно и то же время, они оба могут выполнить test
прежде чем кто-либо из них доберется до touch
, Тогда они в конечном итоге перезаписывают файлы друг друга.
Правильное решение заключается в использовании атомного теста и набора. Распространенным и простым решением является использование временного каталога и выход из него, если mkdir
терпит неудачу; в противном случае у вас есть замок.
# Try to grab lock; yield if unsuccessful
mkdir /tmp/backup_daily_lockdir || exit 1
# We have the lock; set up to remove on exit
trap "rmdir /tmp/backup_daily_lockdir" EXIT
# Also run exit trap if interrupted
trap 'exit 127' SIGINT SIGTERM
: the rest of your script here
Существуют и другие общие решения, но они не имеют внешних зависимостей и очень просты в реализации и понимании.