Shell脚本:如果已经运行,请确保不执行脚本[重复]

Posted

技术标签:

【中文标题】Shell脚本:如果已经运行,请确保不执行脚本[重复]【英文标题】:Shell script: Ensure that script isn't executed if already running [duplicate] 【发布时间】:2011-06-13 17:19:54 【问题描述】:

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

我已经设置了一个 cronjob 来正确备份我的文件夹,这让我感到非常自豪。但是,通过查看备份结果,我发现我的备份脚本已被 Crontab 多次调用,导致同时运行多个备份。

如果同一个脚本已经在执行,我有什么办法可以确保某个 shell 脚本不会运行?

【问题讨论】:

类似问题:***.com/questions/1440967/… 请看Process Management。 【参考方案1】:

没有竞争条件或提前退出问题的解决方案是使用锁定文件。 flock 实用程序可以很好地处理这个问题,可以这样使用:

flock -n /var/run/your.lockfile -c /your/script

如果脚本已经在运行,它将立即返回非 0 状态。

【讨论】:

【参考方案2】:

通常和简单的方法是这样写:

if [[ -f /tmp/myscript.running ]] ; then
    exit
fi
touch /tmp/myscript.running

在你的脚本顶部和

rm -f /tmp/myscript.running

在结尾处,并在trap 函数中,以防它没有到达结尾。

这仍然存在一些潜在问题(例如顶部的竞争条件),但适用于绝大多数情况。

【讨论】:

这将阻止脚本在之前运行过。 @unbeli:不,不会,因为您在退出时删除了哨兵文件。 由于“文件不存在”和“创建文件”之间的 TOCTOU(检查时间、使用时间)存在竞争条件。原子机制是mkdir /tmp/myscript.running 2>/dev/null。如果该目录存在,mkdir 将失败,内核确保只有一个并发运行的mkdir 命令(系统调用)成功。 我评论时rm不在。无论如何,这个解决方案远不是最好的。 如果脚本在运行时崩溃/被杀死/重启怎么办?脚本将永远不会再次运行。好的,重启会清除 /tmp,但你明白了。【参考方案3】:

没有锁文件的好办法:

ps | grep $0 | grep -v grep > /var/tmp/$0.pid
pids=$(cat /var/tmp/$0.pid | cut -d ' ' -f 1)
for pid in $pids
do
   if [ $pid -ne $$ ]; then
      logprint " $0 is already running. Exiting"
      exit 7
   fi
done
rm -f /var/tmp/$0.pid

这样做没有锁定文件,这很酷。 ps 到一个临时文件中,刮掉第一个字段(pid #)并自己寻找。如果我们找到一个不同的,那么有人已经在运行了。 grep $0 将列表缩短为仅包含该程序的那些实例,并且 grep -v grep 摆脱了 grep 本身的行:)

【讨论】:

使用pgrep更简单:pids=$(pgrep $0); for pid in $pids【参考方案4】:

您可以使用 tmp 文件。 将其命名为 tmpCronBkp.a、tmpCronBkp.b、tmpCronBkp.c...等。与您的备份脚本相关。

在脚本开始时创建它并在最后删除它...

一会儿,检查文件是否存在以及存在什么文件。

你试过这种方式吗?

【讨论】:

我不确定我是否完全清楚,但我想确保我的 shell 脚本不会再次执行,如果它已经被 CRON 调用并处于活动状态 让这个文件保存已启动进程的PID。因此,您将能够弄清楚它是否正在运行。 是的,你可以检查tmp文件,如果文件存在则退出scrit!

以上是关于Shell脚本:如果已经运行,请确保不执行脚本[重复]的主要内容,如果未能解决你的问题,请参考以下文章

菜鸟一位想写一个linux shell 脚本,执行次脚本回显数字,执行第一次回显1,执行第二次显示2,以此类推...

如何让安卓手机开机自动执行某一脚本

仅当文件存在于 shell 脚本中时才移动

shell脚本在后台运行以及日志重定向输出

如何执行PHP脚本

Shell脚本编程之Shell输入/输出重定向