备份脚本需要一个 pid 锁来防止多个实例
Posted
技术标签:
【中文标题】备份脚本需要一个 pid 锁来防止多个实例【英文标题】:backup script requires a pid lock to prevent multiple instances 【发布时间】:2014-07-10 02:26:27 【问题描述】:我有一个运行每日 rsync 增量备份的 bash 脚本。
我的问题是我最终运行了多个实例。我是 bash 脚本的新手,所以我不确定我的脚本是否有问题?贴在下面。
但我读过关于 pid 锁定文件的信息?
谁能告诉我如何将它添加到我的脚本中?
#!/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
【问题讨论】:
【参考方案1】:您提出的解决方案存在竞争条件。如果两个实例几乎同时运行,它们都可以在其中任何一个到达touch
之前执行test
。然后他们最终会覆盖彼此的文件。
正确的解决方法是使用原子测试和设置。一个常见且简单的解决方案是使用临时目录,如果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
还有其他常见的解决方案,但这没有外部依赖,非常容易实现和理解。
【讨论】:
好的,我将如何将这个方法写入我的脚本? 另一种可能性是创建一个临时文件并尝试mv tempfile lockfile
- 至少在大多数常见文件系统上,重命名应该是原子的。不过,它可能无法得到普遍保证......【参考方案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 命名。
【讨论】:
是的,就像这样;) 嗯,我收到此错误 # sh /usr/local/src/backup/backup_daily_v3.sh 星期三 /usr/local/src/backup/backup_daily_v3.sh:第 30 行:意外标记附近的语法错误 @ 987654322@rm -f /tmp/backup_daily_lockfile #rsync之后' @Kevin 脚本与您在问题中发布的完全一样? 你能在评论中粘贴第 30 行吗?以上是关于备份脚本需要一个 pid 锁来防止多个实例的主要内容,如果未能解决你的问题,请参考以下文章
tinyMCE - 防止在一个页面上使用原始 id 作为名称/多个实例