当前位置:首页 > 尘凡 > 正文内容

Shell脚本flock加锁实现单实例运行

满纸空言3年前 (2021-12-31)尘凡20510

转自:https://www.cnblogs.com/jmliao/p/11506690.html

命令简介

NAME
flock - manage locks from shell scripts

SYNOPSIS
flock [options] <file|directory> [command args]
flock [options] <file|directory> -c 
flock [options]

应用场景

在设置定时任务crontab时,如果脚本不支持单实例运行,当某一次定时任务中脚本运行时间较长,下一次定时任务又会启动一个脚本,会导致出现多个实例。若进程太多,会占用大量的CPU资源,导致机器down掉。

解决方案:通过加锁来实现脚本的单实例运行。

示例

  1. 脚本内部加锁
#!/bin/bash

{
    flock –n 3
    [$? –eq 1] && { echo fail; exit}
    echo succeed
    #Do your task here …

} 3<>mylockfile

首先使用<>打开mylockfile 并定向到文件描述符3,而定向文件描述符是先于命令执行的,因此假如要执行的语句段中需要读写mylockfile文件。例如想获得上一个脚本实例的 pid,并将此次的脚本实例的pid写入mylockfile。此时直接用>打开mylockfile会清空上次存入的内容,而用<打开 mylockfile当它不存在时会导致一个错误。

或者使用下面的方法:

#!/bin/bash

exec 6>mylockfile
flock -xn 6
[$? –eq 1] && { echo fail; exit}
#Do your task here …

flock -u 6
exec 6>$-
  1. 脚本外加锁

上面的方法中,有一个缺陷是需要使用有一个文件描述符。若这个文件描述符被别的程序占用,再使用的话会有冲突。

* * *  *  * root /bin/bash flock -xn mylockfile /bin/bash my.sh

这种情况下,脚本执行完成或被kill掉,会自动释放文件的锁。

  1. 原理

在第2中使用方法中,实际上是启动了两个进程,flock是父进程,my.sh是子进程。当父进程被kill后,my.sh成为了孤儿进程,但是此时仍然保持有mylockfile的锁。再使用flock加锁执行脚本,无法获取到锁,执行失败。

对于后台进程来说,父进程退出后子进程仍然拥有mylockfile的锁。

  1. 注意点

上面的两种方法都能用来实现shell脚本的加锁,但是有一个问题需要注意,在使用加锁启动的脚本中,若启动了子进程,当父进程退出后,子进程仍然持有锁。例如在my.sh中加入sleep 3600,当kill掉my.sh后,mylockfile仍然会被sleep进程持有锁。

扫描二维码推送至手机访问。

版权声明:本文由满纸空言发布,如需转载请注明出处。

本文链接:https://mzky.cc/post/78.html

分享给朋友:

“Shell脚本flock加锁实现单实例运行” 的相关文章

golang的os包使用备忘4年前 (2021-04-21)
golang计算中文文字数量4年前 (2021-04-21)
keepalived+lvs配置3年前 (2021-05-12)
CSRF漏洞修复3年前 (2021-06-10)
红旗11系统下载3年前 (2021-07-09)
uos编译njmon3年前 (2021-07-21)

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。