备份脚本需要pid锁以防止多个实例

时间:2014-05-21 12:33:11

标签: bash pid lockfile

我有一个运行每日rsync增量备份的bash脚本。

我的问题是我最终运行了多个实例。我是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 个答案:

答案 0 :(得分:1)

将以下内容添加到您的脚本中:

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命名。

答案 1 :(得分:0)

您提出的解决方案存在竞争条件。如果两个实例几乎同时运行,则在test之前,它们都可以执行touchmkdir。然后他们最终会覆盖彼此的文件。

正确的解决方法是使用原子测试并设置。一个常见而简单的解决方案是使用临时目录,如果# 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 失败则退出;否则,你有锁。

{{1}}

还有其他常见的解决方案,但这没有外部依赖关系,并且很容易实现和理解。