如何确保一次只运行一个Bash脚本实例?

Nig*_*olf 10 linux bash concurrency scheduled-tasks

我想创建一个只能在任何时候运行一次的sh脚本.

比方说,如果我执行脚本,那么我再次执行脚本,如何使脚本如果脚本的第一个exec仍在工作,第二个脚本将失败并显示错误.即我需要在做任何事情之前检查脚本是否在其他地方运行.我该怎么做呢?

我运行的脚本运行一个长时间运行的过程(即永远运行).我想使用像cron之类的东西每隔15分钟调用一次脚本,这样如果进程失败,它将由下一个cron运行脚本重新启动.

cxr*_*reg 16

你想要一个pid文件,可能是这样的:

pidfile=/path/to/pidfile
if [ -f "$pidfile" ] && kill -0 `cat $pidfile` 2>/dev/null; then
    echo still running
    exit 1
fi  
echo $$ > $pidfile
Run Code Online (Sandbox Code Playgroud)

  • 我已经读过PID文件不是解决这个问题的好方法......鉴于某些进程可以采用相同的PID等. (2认同)

ale*_*oid 9

我认为你需要使用lockfile命令.请参阅在shell脚本(BASH)http://www.davidpashley.com/articles/writing-robust-shell-scripts.html中使用lockfiles.

第二篇文章使用"手工制作的锁文件",并展示如何捕获脚本终止和释放锁; 虽然lockfile -l <timeout seconds>在大多数情况下使用可能是一个很好的选择.

没有超时的使用示例:

lockfile script.lock
<do some stuff>
rm -f script.lock
Run Code Online (Sandbox Code Playgroud)

将确保在此过程中启动的任何第二个脚本将无限期地等待文件被删除,然后再继续.

如果我们知道脚本的运行时间不应超过X秒,并且script.lock仍然存在,则可能意味着脚本的先前实例在删除之前被终止script.lock.在这种情况下,我们可以告诉lockfile强制在超时后重新创建锁(X = 10以下):

lockfile -l 10 /tmp/mylockfile
<do some stuff>
rm -f /tmp/mylockfile
Run Code Online (Sandbox Code Playgroud)

由于lockfile可以创建多个锁定文件,因此有一个参数可以指导它在重试获取所需的下一个文件之前应该等待多长时间(-<sleep before retry, seconds>-r <number of retries>).-s <suspend seconds>当强制移除锁时,还有一个等待时间的参数(这种补充了强制断开锁之前用来等待的超时).

  • 虽然此链接可能会回答这个问题,但最好在此处包含答案的基本部分并提供参考链接.如果链接的页面发生更改,则仅链接的答案可能会无效. - [来自评论](/ review/low-quality-posts/18981146) (2认同)

blu*_*yed 5

您可以使用run-one提供run-onerun-this-one和的包keep-one-running

包:https : //launchpad.net/ubuntu/+source/run-one

介绍它的博客:http : //blog.dustinkirkland.com/2011/02/introducing-run-one-and-run-this-one.html