共享一个防止脚本重复启动的shell脚本
项目的一个需求:为防止脚本重复调度,导致同时运行时相互冲突,需要在脚本运行开始前创建一个文件,结束时删除。
脚本启动时判断一下文件是否存在,如果存在则退出。
最开始这样做没发现问题,但跑一段时间后,发现如果进程中间退出没删除文件就会出现问题。
而且有时希望等待一段时间后不管有没有已启动同名脚本,都往下走。
基于以上考虑,最近将这个防止重复启动的逻辑抽离出来成为独立脚本,并增加了一些控制逻辑,这样以后需要类似功能直接调用这个脚本就好。
流程图:

代码:
#! /bin/sh
# singleton.sh 进程名($0) 进程id($$) 工作目录 休眠时间 尝试次数
# 尝试次数为0代表无限次
# 本脚本的作用是防止进程重复启动(类似单例) 脚本启动后会在工作目录生成一个进程信息文件(pidfile)起到唯一锁作用
# 如果pidfile里面的进程不存在 脚本就会结束 否则会一直等待直到尝试次数超限 if [ $# != 5 ]
then
echo "usage:singleton.sh 进程名(\$0) 进程id(\$\$) 工作目录 休眠时间 尝试次数(0代表无限次)"
exit 1
fi v_proc_name=${1##*/}
v_pid=$2
v_work_dir=$3
v_sleep_seconds=$4
v_retry_times=$5
# pid文件路径 模拟文件锁用的
v_pid_file=${v_work_dir}/singleton_run_pid echo "cmd = $0 $*" # 判断pid文件是否存在
# 如存在判断文件里面的进程是否存在 且进程名字相同
# 如果符合以上条件则休眠后再次尝试 直至满足最大尝试次数
if [ -f ${v_pid_file} ]
then
echo "file[${v_pid_file}] exists!" v_times=0
v_max_retry_times=${v_retry_times}
while [ ${v_times} -lt ${v_max_retry_times} -o ${v_retry_times} -eq 0 ]
do
v_pid_old="";v_proc_name_old="";
read v_pid_old v_proc_name_old < ${v_pid_file} if [ "${v_pid_old}" = "" -o "${v_proc_name_old}" = "" ]
then
echo "error pidfile [$(cat ${v_pid_file})]"
break;
fi # 考虑到脚本有时被强制杀掉会导致pid文件残留没清理,这里加上对pid文件内容判断
if [ ${v_proc_name_old} != ${v_proc_name} ]
then
echo "proc_name not euqal; [${v_proc_name_old}] != [${v_proc_name}]! do next;"
break;
fi if [ ${v_pid} = ${v_pid_old} ]
then
echo "pid euqal; [${v_pid}] = [${v_pid_old}]! do next;"
break;
fi # grep 参数 -- 代表参数结果 后面跟的是关键字或文件名 这是为了避免进程名是-bash的问题
v_pid_inf=$(ps -ef|awk -v v_pid_old=${v_pid_old} '{ if($2 == v_pid_old) print $0; }'|grep -w -- ${v_proc_name})
if [ "${v_pid_inf}" = "" ]
then
echo "cannot find the pid[ps -ef|awk -v v_pid_old=${v_pid_old} '{ if(\$2 == v_pid_old) print \$0; }'|grep -w -- ${v_proc_name}]! do next;"
break;
fi v_times=$(expr ${v_times} + 1)
echo "try times ${v_times}; sleep ${v_sleep_seconds}"
sleep ${v_sleep_seconds}
done echo "had tried ${v_times} times! do next;"
fi echo "create file[${v_pid_file}]!"
echo ${v_pid} ${v_proc_name} > ${v_pid_file}
共享一个防止脚本重复启动的shell脚本的更多相关文章
- centos shell脚本编程1 正则 shell脚本结构 read命令 date命令的用法 shell中的逻辑判断 if 判断文件、目录属性 shell数组简单用法 $( ) 和${ } 和$(( )) 与 sh -n sh -x sh -v 第三十五节课
centos shell脚本编程1 正则 shell脚本结构 read命令 date命令的用法 shell中的逻辑判断 if 判断文件.目录属性 shell数组简单用法 $( ) 和$ ...
- 一个备份MySQL数据库的简单Shell脚本(转)
Shell脚本是我们写不同类型命令的一种脚本,这些命令在这一个文件中就可以执行.我们也可以逐一敲入命令手动执行.如果我们要使用shell脚本就必须在一开始把这些命令写到一个文本文件中,以后就可以随意反 ...
- [转]一个备份MySQL数据库的简单Shell脚本
本文翻译自 iSystemAdmin 的 <A Simple Shell Script to Backup MySQL Database> Shell脚本是我们写不同类型命令的一种脚本,这 ...
- spring boot 以jar的方式启动常用shell脚本
用spring boot框架做的项目,将第三方包全部打在jar里面,通过shell脚本启动和停止服务,常用的shell脚本模板如下: #!/bin/bashJAVA_OPTIONS_INITIAL=- ...
- 一个自动安装LNMP的简洁Shell脚本
此脚本在生产服务器上使用了一年多,本脚本崇尚简单唯美,只需要一个脚本就可以在任何一台有网络的服务器上自动配置LNMP.本脚本会在脚本执行目录下,建packages目录用于存放LNMP所需要的软件.大家 ...
- smbtar - 直接备份SMB/CIFS共享资源到UNIX磁带设备的shell脚本
总览 smbtar -s server [-p password] [-x service] [-X] [-d directory] [-u user] [-t tape] [-b blocksize ...
- 做一个创建cocos2d-x新项目的shell脚本
1. 进入console目录 cd /Users/apple/Documents/MyArchitecture/Cocos2d-x/Framework/cocos2d-x-3.4/tools/coco ...
- shell脚本实例,通向shell脚本大师的必经之路
概述 读书百遍其义自见,shell脚本也是,只要例子看得多了,自然就知道怎么写了.这里主要整理了20几个例子,因为内容比较多,所以分了几次来做介绍了.下面的实例最好先自己思考怎么去实现,然后再看下实现 ...
- 面试笔试-脚本-1:使用shell脚本输出登录次数最多的用户
原题目: 一个文本类型的文件,里面每行存放一个登陆者的IP(某些行是反复的),写一个shell脚本输出登陆次数最多的用户. 之前刚看到这个题目时,立即没有想到一行直接解决的办法,尽管知道能够先进行排序 ...
随机推荐
- shell脚本中echo显示内容带颜色
转自:http://www.cnblogs.com/lr-ting/archive/2013/02/28/2936792.html shell脚本中echo显示内容带颜色显示,echo显示带颜色,需要 ...
- Java中的浅复制和深复制 Cloneable clone
先看一个简单案例 public class Test { public static void main(String args[]) { Student stu1 = new ...
- MySQL存储过程(一)
1.1 CREATE PROCEDURE (创建) CREATE PROCEDURE存储过程名 (参数列表) BEGIN SQL语句代码块 END 注意: 由括号包围的参数列必须总是存在.如果没有参 ...
- My.Ioc 代码示例——注册项的注销和更新
当您需要从 Ioc 容器中注销/删除一个注册项的时候,您会怎么做呢? 有人曾经在 stackoverflow 上提问“如何从 Unity 中注销一个注册项”.对于这个问题,有人的回答是“有趣.你为什么 ...
- leetcode修炼之路——13. Roman to Integer
题目: Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from ...
- 启动php-fpm时报错
[root@localhost ~]# /usr/local/php/sbin/php-fpm [06-Aug-2012 19:17:53] ALERT: [pool www] pm.min_spar ...
- Delphi 动态改变Rzsplitter的Orientation(方向)属性
效果图: 原先不知道,弄了半天都改不了RzSplitter.Orientation = orHorizontal / orVertical 然后去查该组件的源代码,原来Orientation不是在Rz ...
- [LeetCode OJ] Max Points on a Line—Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
//定义二维平面上的点struct Point { int x; int y; Point(, ):x(a),y(b){} }; bool operator==(const Point& le ...
- javascript学习(知识点整理)
有了这个代码,就可以在定义 中增加更多的控制了 后面会举例关于extjs定义的更多控制 此种方案可以解决定义时需要一些函数调用的情况 函数作用域和声明提前: 即由于js是解释性语言,在执行前会 ...
- UI基础 - UINavigationController
如果导航控制器的BarButtonItem属性是一致的,可以重写initialize方法用来设置主题 //再ViewDidload执行前只执行一次 +(void)initialize { //创建的U ...