用于确保在任何给定时间仅运行一个 shell 脚本的 shell 片段 [重复]
Posted
技术标签:
【中文标题】用于确保在任何给定时间仅运行一个 shell 脚本的 shell 片段 [重复]【英文标题】:Shell fragment to make sure only one instance a shell script runs at any given time [duplicate] 【发布时间】: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 版本的奖励积分。
【问题讨论】:
【参考方案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 ...
您可以指定重试和等待时间。这是专门为此目的创建的,因此它可以处理竞争条件
【讨论】:
以上是关于用于确保在任何给定时间仅运行一个 shell 脚本的 shell 片段 [重复]的主要内容,如果未能解决你的问题,请参考以下文章