您的位置:首页 > 运维架构 > Shell

防止shell脚本重复执行

2011-08-30 21:33 441 查看
利用锁机制,让一个特定的shell脚本,每次只能运行一个实例。具体来说,获得锁的脚本实例,能够继续往下执行临界区代码;没有获得锁的实例,则只能等待。

例如,要求脚本只能顺序访问某个资源,例如磁盘文件等,就可以参考下面的实现。

#!/bin/bash
#
# file locking using bash.
# ver 0.1.6
#
# author : malundao ( malundao@sina.com )
# date   : 2011-08-31
# ref    : http://unix.derkeiler.com/Newsgroups/comp.unix.shell/2005-09/0472.html #
# note:
#   shflock_cleanhook() is a user defined function to clean up user-specific sth.
#

# /path/to/lock/. note; directory, not a file.
# should be modified
LOCKPATH="/tmp"

cleanup() {
shflock_cleanhook

cd $LOCKPATH
[ -e lock.pid ] || exit

read pid >/dev/null 2>&1 <lock.pid
if [ -n "$pid" ]; then
if [ "$pid" == "$$" ]; then
rm -f lock.$pid
rm -f lock.pid
exit
fi
fi
exit
}

#  trap EXIT ?
trap 'cleanup' HUP INT TERM

getlock() {
oldpath=`pwd`
cd $LOCKPATH
while
echo $$ > lock.$$
[ -e lock.pid ]
do
rm lock.$$
read pid >/dev/null 2>&1 <lock.pid
if [ -n "$pid" ]; then
if [ -e /proc/$pid ]; then
cd $oldpath
return 1 # Lock is taken by others
else
#unsafe: rm -f lock.$pid
echo WARN: please delete stale lock.pid by HAND.
return 2
fi
else
# sleep some seconds,then back to 'while' loop
# 11 is a prime number, $$ as a random.
echo sleep $(( $$ % 11 ))
sleep $(( $$ % 11 ))
fi
done
# 'ln -s' is an atom op.
ln -s lock.$$ lock.pid >/dev/null 2>&1
if [ $? -eq 0 ]; then
cd $oldpath
return 0 # We got the lock
else
[ -e lock.pid ] || echo WARN: please delete hanging lock.pid by HAND.
cd $oldpath
return 3 # Lock is probably taken by others.
fi
}

putlock () {
oldpath=`pwd`
cd $LOCKPATH && rm -f lock.$$ lock.pid
cd $oldpath
}

## test
shflock_cleanhook() {
echo i\'m a hook.
}
while true; do
while ! getlock; do
#echo wait a second...
sleep 1
done

echo \[$$\] `date` ,now hold lock for 3 seconds...
sleep 3
#echo putlock
putlock
sleep 1 # yield
done
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: