У меня есть этот сценарий bash, который регулярно запускается через cron:
#!/bin/bash
RSYNC=/usr/bin/rsync
SSH=/usr/bin/ssh
KEY=/Users/admin/Documents/Backup/rsync-key
RUSER=philosophy
RHOST=example.com
RPATH=data/
LPATH="/Volumes/G Technology G Speed eS/Backup"
LOCKFILE=/Users/admin/Documents/backup.isrunning
if [ ! -e $LOCKFILE ]; then
touch $LOCKFILE
$RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH
rm $LOCKFILE
else
echo "Rsync - Backup still running"
fi
Резервное копирование может занять любое время, от нескольких минут до нескольких дней, и если я буду запускать резервное копирование через cron каждые 6 часов, то мне не нужно, чтобы два экземпляра этого выполнялись одновременно. Итак, я создал простой механизм блокировки. Но меня беспокоит, что если сценарий будет прерван на полпути по какой-либо причине, этот файл блокировки всегда будет там, и процедура резервного копирования не будет запущена.
Есть ли способ улучшить защиту от дурака?
Спасибо
Скотт
РЕДАКТИРОВАТЬ: Последний сценарий bash, который я сейчас использую, благодаря ответу ниже:
#!/bin/bash
RSYNC=/usr/bin/rsync
SSH=/usr/bin/ssh
KEY=/Users/admin/Documents/Backup/rsync-key
RUSER=philosophy
RHOST=example.com
RPATH=data/
LOCKFILE=/Users/admin/Documents/Backup/backup.isrunning
if [ ! -e $LOCKFILE ]
then
echo $$ >"$LOCKFILE"
else
PID=$(cat "$LOCKFILE")
if kill -0 "$PID" >&/dev/null
then
echo "Rsync - Backup still running"
exit 0
else
echo $$ >"$LOCKFILE"
echo "Warning: previous backup appears to have not finished correctly"
fi
fi
LPATH="/Volumes/G Technology G Speed eS/Backup"
$RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH
LPATH="/Volumes/G Technology G Speed eS/Catalogue"
$RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH
LPATH="/Volumes/G Technology G Speed eS/Digital"
$RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH
LPATH="/Volumes/G Technology G Speed eS/Finance"
$RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH
LPATH="/Volumes/G Technology G Speed eS/Image Libraries"
$RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH
LPATH="/Volumes/G Technology G Speed eS/IT Desk"
$RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH
LPATH="/Volumes/G Technology G Speed eS/Office"
$RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH
LPATH="/Volumes/G Technology G Speed eS/Studio"
$RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH
LPATH="/Volumes/G Technology G Speed eS/Toffee Apple"
$RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH
rm -f "$LOCKFILE"
Если вы поместите PID сценария в файл блокировки, то, если файл блокировки существует при запуске нового экземпляра, вы можете прочитать PID и проверить, выполняется ли все еще сценарий. Если скрипт не запущен, выполните очистку, поместите PID текущего экземпляра в файл блокировки и запустите rsync, в противном случае выведите сообщение «все еще выполняется» и выйдите.
РЕДАКТИРОВАТЬ:
#!/bin/bash
backup() {
RSYNC=/usr/bin/rsync
SSH=/usr/bin/ssh
KEY=/Users/admin/Documents/Backup/rsync-key
RUSER=philosophy
RHOST=example.com
RPATH=data/
LPATH="/Volumes/G Technology G Speed eS/Backup"
$RSYNC -avz --delete --progress -e "$SSH -i $KEY" "$LPATH" $RUSER@$RHOST:$RPATH
}
LOCKFILE=/Users/admin/Documents/backup.isrunning
if [ ! -e "$LOCKFILE" ]
then
echo $$ >"$LOCKFILE"
backup
else
PID=$(cat "$LOCKFILE")
if kill -0 "$PID" >&/dev/null
then
echo "Rsync - Backup still running"
exit 0
else
echo $$ >"$LOCKFILE"
echo "Warning: previous backup appears not to have finished correctly"
backup
fi
fi
rm -f "$LOCKFILE"
Если вы настраиваете несколько резервных копий, вы можете взглянуть на LBackup который предлагает блокировку, а также полностью поддерживает резервное копирование по запросу. Дополнительная информация о преимуществах резервного копирования по запросу доступна по следующему URL-адресу: http://www.lbackup.org/network_backup_strategies
Если вы проверите исходный код LBackup, вы увидите, как реализована система блокировки с использованием ловушки. Приведенное выше предложение относительно использования PID также является хорошей идеей. При таком подходе, если весь сервер выйдет из строя, и ловушка не сможет сработать.