作者:守望,linux应用开发者,目前在公众号【编程珠玑】 分享Linux/C/C++/数据结构与算法/工具等原创技术文章和学习资源。
成都创新互联公司专业为企业提供龙安网站建设、龙安做网站、龙安网站设计、龙安网站制作等企业网站建设、网页设计与制作、龙安企业网站模板建站服务,十余年龙安做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。
假设你的一个脚本已经在运行了,如果避免再次被执行呢?也就是如何实现单例运行?
看起来可行的方法
一个非常简单的思路就是,新的脚本被执行时,先检测当前脚本是否有其他实例正在运行,如果有则直接退出。
- #!/usr/bin/env bash
- #test.sh 来源:公众号编程珠玑
- #获取当前运行的test.sh脚本数
- runCount=$(ps -ef|grep test.sh | grep -v grep -c)
- if [ "${runCount}" -ge 1 ]
- then
- echo -e "test.sh already running,num:${runCount}"
- exit 1;
- fi
- while true
- do
- echo "test.sh run"
- sleep 1
- done
这里通过ps获取到当前在运行的test.sh脚本数,如果大于1,说明已经有在运行的了。
但是你运行会发现,其程序数量不只是一个。
- $ ./test.sh
- test.sh already running,num:2
惊不惊喜?为什么为这样呢?原因在于,shell脚本中一个命令执行相当于fork了一个进程执行,这里执行的是查找tesh.sh并grep的程序,另外还有一个就是当前运行的脚本程序,这样的方式自然就会出现每次都有两个了。
当然判断条件这里你可以换一下,例如数量大于2,但终归不太好。
文件锁
实际上这种方法你已经在《如何让你的程序同时只有一个在运行》介绍过了,只不过之前是用于编写C/C++程序,而这里是用于shell脚本。
我们来回顾一下,这是一个怎样的过程:
解释一下第一条,为什么一定要确定锁文件中的进程正在运行,因为,有些情况下如果运行的时候退出没有删除该文件,则会导致新的实例永远无法运行。
- #!/usr/bin/env bash
- #来源:公众号编程珠玑
- LOCKFILE=/tmp/test.lock
- if [ -e ${LOCKFILE} ] && kill -0 `cat ${LOCKFILE}`; then
- echo " $0 already running"
- exit
- fi
- # 确保退出时,锁文件被删除
- trap "rm -f ${LOCKFILE}; exit" INT TERM EXIT
- #将当前程序进程id写入锁文件
- echo $$ > ${LOCKFILE}
- # 做你需要的事情
- sleep 1000
- # 删除锁文件
- rm -f ${LOCKFILE}
我们试着运行其中一个,然后另外一个窗口尝试运行:
- $ ./test.sh
- ./test.sh already running
由于已经有实例在运行,发现新的程序无法运行了。而等旧的脚本运行完之后,新的就可以运行了。
实际上这里面有几个点非常巧妙:
flock
说到锁文件,这里就不得不提flock命令了。没有前面的一些巧妙处理,我们很多时候会很难删除原先创建的锁文件,比如:
因此我们可以考虑使用flock:
- #!/usr/bin/env bash
- #来源:公众号编程珠玑
- LOCK_FILE=/tmp/test.lock
- exec 99>"$LOCK_FILE"
- flock -n 99
- if [ "$?" != 0 ]; then
- echo "$0 already running"
- exit 1
- fi
- #脚本要做的其他事情
- sleep 1024
解释一下:
因此这里避免了锁没有释放的情况。
另一种做法
查看flock的man手册,我们发现它还有一个例子是这么做的:
- [ "${FLOCKER}" != "$0" ] && exec env FLOCKER="$0" flock -en "$0" "$0" "$@" || :
在脚本开头加上上面这么一行就可以了。例如:
- #!/usr/bin/env bash
- #来源:公众号编程珠玑
- [ "${FLOCKER}" != "$0" ] && exec env FLOCKER="$0" flock -en "$0" "$0" "$@" || :
- #脚本要做的其他事情
- sleep 1024
解释一下:
总结
单例运行本身思路是很简单的,就是探测当前是否有实例在运行,如果有,则退出,但是这里如何判断,却并不是那么容易。
最后,总结一下本文出现的一些该掌握的信息
本文转载自微信公众号「 编程珠玑」,可以通过以下二维码关注。转载本文请联系 编程珠玑公众号。
新闻标题:怎么正经的实现Shell脚本单例运行?
网站路径:http://www.mswzjz.com/qtweb/news20/185220.html
成都网站建设公司_创新互联,为您提供微信小程序、营销型网站建设、标签优化、网站导航、动态网站、ChatGPT
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联