【问题标题】:bash script flock() locking and starting servicebash脚本flock()锁定和启动服务
【发布时间】:2015-10-21 18:30:43
【问题描述】:

我想使用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

这是一种合理的方法吗?

【问题讨论】:

    标签: linux bash shell flock


    【解决方案1】:

    为了防止脚本并行运行,我建议这样做。

    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 被其他脚本删除时它不起作用。

    【讨论】:

    • 感谢您的评论,但这并不能回答我的问题。首先,我使用的是flock,而不是简单的检查文件是否存在。 Flock 也是原子的,如果服务器意外重新启动,并且临时文件/目录仍然存在,它也可以工作。
    猜你喜欢
    • 1970-01-01
    • 2016-11-26
    • 1970-01-01
    • 2015-11-02
    • 2015-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多