【问题标题】:Shell fragment to make sure only one instance a shell script runs at any given time [duplicate]用于确保在任何给定时间仅运行一个 shell 脚本的 shell 片段 [重复]
【发布时间】:2010-10-31 20:42:10
【问题描述】:

可能重复:
Quick-and-dirty way to ensure only one instance of a shell script is running at a time

在以前的工作场所,我们曾经有一个高度精炼的 bash 函数,称为 run-only-once,我们可以将它写入任何长时间运行的 shell 脚本,然后在脚本的开头调用它,它会检查查看脚本是否已经作为另一个进程运行,如果是,则退出并通知 STDOUT。

有没有人可以分享这样的函数/片段?

我们的旧函数(我不再拥有)将检查 /var/run 中的 PID 文件(以 scriptname.$$ 格式),然后使用退出或简单地继续。在存在 PID 文件的情况下,它会进行一些检查以确保进程仍然处于活动状态。它还有一些选项可以控制是否输出通知。

根据记忆,我们的函数只能在 bash 中工作。 /bin/sh 版本的奖励积分。

【问题讨论】:

    标签: shell


    【解决方案1】:

    把它放在脚本的开头

    SCRIPTNAME=`basename $0`
    PIDFILE=/var/run/${SCRIPTNAME}.pid
    
    
    if [ -f ${PIDFILE} ]; then
       #verify if the process is actually still running under this pid
       OLDPID=`cat ${PIDFILE}`
       RESULT=`ps -ef | grep ${OLDPID} | grep ${SCRIPTNAME}`  
    
       if [ -n "${RESULT}" ]; then
         echo "Script already running! Exiting"
         exit 255
       fi
    
    fi
    
    
    #grab pid of this process and update the pid file with it
    PID=`ps -ef | grep ${SCRIPTNAME} | head -n1 |  awk ' {print $2;} '`
    echo ${PID} > ${PIDFILE}
    

    最后

    if [ -f ${PIDFILE} ]; then
        rm ${PIDFILE}
    fi
    

    首先检查 pid 文件是否存在,如果存在则退出。如果是这样,则它确认在此脚本名称下使用旧 pid 的进程正在运行,如果是,则退出。如果不是,那么它会继续并使用新的 pid 文件更新脚本。最后的位检查pid文件是否存在并将其删除,以便脚本可以下次运行。

    检查 /var/run 的权限是否适合您的脚本,否则在另一个目录中创建 PID 文件。与脚本运行的目录相同即可。

    【讨论】:

    • 好答案,我可能会使用它,或者将它与 Nik 指出的问题 185451 的答案结合起来(即我将使用陷阱并杀死 -0)。
    • 还有,能不能不用$$来获取这个进程的PID?
    【解决方案2】:

    有两种方法可以从 shell 执行原子锁。最简单、最便携的是mkdir。如果同名的文件/目录已经存在,创建目录将总是失败,因此只需使用“锁定目录”而不是“锁定文件”即可。

    mkdir "$LOCK" || { echo "Script already running" ; exit 1 ; }
    

    另一种方法是 noclobber 选项,使用set -C 设置。此选项强制 shell 使用 O_EXCL 标志打开文件以进行输出重定向。像这样使用它:

    set -C
    > "$LOCK" || { echo "Script already running" ; exit 1 ; }
    set +C
    

    您可能更愿意回显当前的 PID 或其他有用的信息来存储在文件中,而不是重定向空命令。

    值得记住的是,一些古老的历史 shell 已经破坏了 noclobber 选项 -C 的实现,它不使用 O_EXCL 而是使用错误的非原子检查文件是否存在。在 21 世纪可能不是问题,但您应该注意以防万一。

    【讨论】:

      【解决方案3】:

      在 Linux 中使用 lockfile 实用程序更可靠。

      来自手册页:

               ...
               lockfile important.lock
               ...
               access_"important"_to_your_hearts_content
               ...
               rm -f important.lock
               ...
      

      您可以指定重试和等待时间。这是专门为此目的创建的,因此它可以处理竞争条件

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-07
        • 2013-04-18
        • 1970-01-01
        • 1970-01-01
        • 2011-06-13
        • 2021-06-03
        相关资源
        最近更新 更多