搜文章
推荐 原创 视频 Java开发 iOS开发 前端开发 JavaScript开发 Android开发 PHP开发 数据库 开发工具 Python开发 Kotlin开发 Ruby开发 .NET开发 服务器运维 开放平台 架构师 大数据 云计算 人工智能 开发语言 其它开发
Lambda在线 > 一碗虾酱 > 让shell脚本实现单例运行的方法--富人靠科技穷人靠变异张伟靠过敏

让shell脚本实现单例运行的方法--富人靠科技穷人靠变异张伟靠过敏

一碗虾酱 2018-02-01

在一些工作场景中,常常会定期执行一些脚本来进行一些动作处理。

比如需要在每小时定时执行一个脚本来将本地的内容打包发送到服务器上,那么我们就可以在crontab下增加自己的脚本。

但有一种情况需要考虑到的是,如果五点开始干活的一个脚本,干到六点还没有干完。而在六点的时候,又定时启动了一次脚本,那么这两个脚本干的活其实是一样的,这样肯定会造成冲突。而我们期望的是每一次脚本的运行都是独立的不会发生运行冲突的。所以,保证脚本运行行在单例模式下是一些场景的必要设计。


单例模式,在设计模式中指的是在程序运行中一个类要保证只有一个实例。又比如一些常见的Windows软件,都需要保证只能开启一个窗口,这就是底层设计模式在界面上的表现。从上面可以知道,在任何开发场景下,都有对程序运行在单例的需求。即使一个小小的脚本也不例外。而加深对单例模式的了解,能够方便一些诡异BUG的排查,比如当脚本发生了不是你预期执行的情况,你就多了一个排查方向,是否是脚本没有单例运行导致。

对脚本的单例设计其实很简单,一种最简单的方法是在脚本运行的过程中对一个flag文件尝试加锁,加锁成功则执行,若加锁失败则代表有脚本在执行,保持单例退出。

还有一种就是在程序运行过程中touch一个flag,flag存在即脚本在运行。这样来保证每次都只有一个脚本在运行。

而今天反而想讨论一下,对于每一个执行的脚本都有自己的进程号,有的方法尝试通过同一脚本程序名与进程号唯一作为单例的判断标准。


(环境是mac OS,所以和linux不同的是并没有/proc文件夹可以查看对应的进程id)

常见的方法是

#如果脚本正在执行,则退出

function keep_singleton()

{

    local tmpfile="/tmp/cus_log_report$$"

    ps -aux | grep "cus_log_report.sh" | grep -v $$ | grep -v grep | grep -v 'sh -c' | awk '{print $2}' > ${tmpfile}

    local processes=`cat ${tmpfile}` 

    rm -rf ${tmpfile}

    if [ "${processes}""empty" != "empty" ]

    then

        echo "already a script running"

        exit 1

    fi

}

keep_singleton


看一个小demo的运行情况,让我们看看这种运行情况是否可靠。

让shell脚本实现单例运行的方法--富人靠科技穷人靠变异张伟靠过敏

让shell脚本实现单例运行的方法--富人靠科技穷人靠变异张伟靠过敏


我在这个脚本中,过滤排除了自己的进程号和grep指令,但是可以看到最终呈现的是一个进程号为 21853 的进程,但是在前台ps的时候可以看到,并没有这个进程,而是可以看到目前脚本进程21852的进程。


这个21853进程其实是该脚本执行过程中,派生出来的子进程,那这样的话,其实一个脚本对应两个进程号,这种进程号的判断方式就不可取了。


对于脚本的运行,机理其实我并没有了解太深。最近找时间再深入研究一下当运行脚本的过程中到底发生了什么,其实这个脚本可以通过strace进行系统调用的跟踪,你可以看到他在其中派生了子进程。这就是为什么会有两个ID的原因。(这方面我理论不深,请明白银儿指教!)


其实判断单例使用一开始讲的两种方式就可以了,但是要保证的是,你的脚本在系统发生异常或者执行过程中用户ctrl-c了,你要确保即使删除你的flag,不然如果flag在脚本运行失败之后没有及时处理,那么脚本永远不会执行了。大家可以使用trap指令来进行保证。


trap "do some cmd" singal


trap监听信号量,在相应的信号发生时,会去执行cmd。你可以在这里做你的flag清理工作。


下周返校日见!🕷



版权声明:本站内容全部来自于腾讯微信公众号,属第三方自助推荐收录。《让shell脚本实现单例运行的方法--富人靠科技穷人靠变异张伟靠过敏》的版权归原作者「一碗虾酱」所有,文章言论观点不代表Lambda在线的观点, Lambda在线不承担任何法律责任。如需删除可联系QQ:516101458

文章来源: 阅读原文

相关阅读

关注一碗虾酱微信公众号

一碗虾酱微信公众号:ubuntu_programmer

一碗虾酱

手机扫描上方二维码即可关注一碗虾酱微信公众号

一碗虾酱最新文章

精品公众号随机推荐