bash脚本flock()锁定和启动服务

时间:2015-07-30 11:54:19

标签: linux bash shell flock

我想使用flock来确保在任何给定时间只运行一次脚本实例。

脚本框架如下所示:

ME=`basename "$0"`;
LOCK="/tmp/${ME}.LCK";
exec 8>$LOCK;



if flock -n -x 8; then
    do things

     if [ condition ]; then
       /path/asterisk_restart.sh
     fi
else
    echo "$(date) script already running >> $log_file"

fi

现在脚本/path/asterisk_restart.sh做了很多事情,但最后星号停止了,最后一个命令是service asterisk start

问题是:由于文件句柄和锁在fork()/exec()之间共享,8文件句柄仍然在星号进程中锁定,因此执行/path/asterisk_restart.sh后脚本不再运行(并且星号不是通过此脚本以外的其他方式停止/重新启动)

所以我的方法是在执行/path/asterisk_restart.sh之前启动子shell并关闭8个文件句柄。

看起来像这样:

    ME=`basename "$0"`;
    LOCK="/tmp/${ME}.LCK";
    exec 8>$LOCK;



    if flock -n -x 8; then
         do things

         if [ condition ]; then
            (
               exec 8>&-
               /path/asterisk_restart.sh
            )
         fi
    else
        echo "$(date) script already running >> $log_file"

    fi

这是一个合理的方法吗?

1 个答案:

答案 0 :(得分:0)

为了防止脚本反对并行运行,我会建议这样的事情。

if mkdir $LockDir; then
    echo "Locking succeeded" >&2
    # Your script here. 
    rm -f $LockDir
else
    echo "Lock failed - exit" >&2
    exit 1
fi

使用目录而不是文件更好,因为mkdir是一个原子操作,因此可以消除竞争条件。

也不要把你的LockDir放在/ tmp里面。如果它被删除,锁定就会消失。

上述实现的唯一问题是,当LockDir被其他一些脚本删除时,它不起作用。