项目的一个需求:为防止脚本重复调度,导致同时运行时相互冲突,需要在脚本运行开始前创建一个文件,结束时删除。

脚本启动时判断一下文件是否存在,如果存在则退出。

最开始这样做没发现问题,但跑一段时间后,发现如果进程中间退出没删除文件就会出现问题。

而且有时希望等待一段时间后不管有没有已启动同名脚本,都往下走。

基于以上考虑,最近将这个防止重复启动的逻辑抽离出来成为独立脚本,并增加了一些控制逻辑,这样以后需要类似功能直接调用这个脚本就好。

流程图:

代码:

#! /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脚本的更多相关文章

  1. centos shell脚本编程1 正则 shell脚本结构 read命令 date命令的用法 shell中的逻辑判断 if 判断文件、目录属性 shell数组简单用法 $( ) 和${ } 和$(( )) 与 sh -n sh -x sh -v 第三十五节课

    centos   shell脚本编程1 正则  shell脚本结构  read命令  date命令的用法  shell中的逻辑判断  if 判断文件.目录属性  shell数组简单用法 $( ) 和$ ...

  2. 一个备份MySQL数据库的简单Shell脚本(转)

    Shell脚本是我们写不同类型命令的一种脚本,这些命令在这一个文件中就可以执行.我们也可以逐一敲入命令手动执行.如果我们要使用shell脚本就必须在一开始把这些命令写到一个文本文件中,以后就可以随意反 ...

  3. [转]一个备份MySQL数据库的简单Shell脚本

    本文翻译自 iSystemAdmin 的 <A Simple Shell Script to Backup MySQL Database> Shell脚本是我们写不同类型命令的一种脚本,这 ...

  4. spring boot 以jar的方式启动常用shell脚本

    用spring boot框架做的项目,将第三方包全部打在jar里面,通过shell脚本启动和停止服务,常用的shell脚本模板如下: #!/bin/bashJAVA_OPTIONS_INITIAL=- ...

  5. 一个自动安装LNMP的简洁Shell脚本

    此脚本在生产服务器上使用了一年多,本脚本崇尚简单唯美,只需要一个脚本就可以在任何一台有网络的服务器上自动配置LNMP.本脚本会在脚本执行目录下,建packages目录用于存放LNMP所需要的软件.大家 ...

  6. smbtar - 直接备份SMB/CIFS共享资源到UNIX磁带设备的shell脚本

    总览 smbtar -s server [-p password] [-x service] [-X] [-d directory] [-u user] [-t tape] [-b blocksize ...

  7. 做一个创建cocos2d-x新项目的shell脚本

    1. 进入console目录 cd /Users/apple/Documents/MyArchitecture/Cocos2d-x/Framework/cocos2d-x-3.4/tools/coco ...

  8. shell脚本实例,通向shell脚本大师的必经之路

    概述 读书百遍其义自见,shell脚本也是,只要例子看得多了,自然就知道怎么写了.这里主要整理了20几个例子,因为内容比较多,所以分了几次来做介绍了.下面的实例最好先自己思考怎么去实现,然后再看下实现 ...

  9. 面试笔试-脚本-1:使用shell脚本输出登录次数最多的用户

    原题目: 一个文本类型的文件,里面每行存放一个登陆者的IP(某些行是反复的),写一个shell脚本输出登陆次数最多的用户. 之前刚看到这个题目时,立即没有想到一行直接解决的办法,尽管知道能够先进行排序 ...

随机推荐

  1. Asp.net中的页面跳转及post数据

    /// <summary> /// This method prepares an Html form which holds all data /// in hidden field i ...

  2. Android 巧妙实现图片和文字布局

    之前写过一个博客是关于实现图片和文字左右或者上下布局的方法, 下面是博客的主要内容: 布局文件很简单,用来展示RadioButton的使用方法. 1 <?xml version="1. ...

  3. 【转】iOS申请发布证书-图文详解

    摘要 发布产品到App Store所需证书,2013年5月26日测试 IOS 发布证书 distribution 打包程序 真机调试证书 本文讲述发布证书的申请,申请真机调试证书请参考:http:// ...

  4. Knockoutjs官网翻译系列(一)

    最近马上要开始一个新项目的研发,作为第一次mvvm应用的尝试,我决定使用knockoutjs框架.作为学习的开始就从官网的Document翻译开始吧,这样会增加印象并加入自己的思考,说是翻译也并不是纯 ...

  5. java对mysql数据库进行单表筛选备份、还原操作

    最近在做的一个项目需要对mysql数据库中的单个表格进行备份 其中,一部分表格需要进行筛选备份(例如对最近插入的1000条记录进行备份) 思路:java调用系统命令完成备份操作 假设现在有数据库tes ...

  6. linux网络编程常用头文件

    sys/types.h:数据类型定义 sys/socket.h:提供socket函数及数据结构 netinet/in.h:定义数据结构sockaddr_in arpa/inet.h:提供IP地址转换函 ...

  7. (兼容IE6)又一个提示框思密达,腾讯UED 201401242352

    找乐子 仿QQ空间的,先来看下,别嫌代码垃圾,业余菜鸟一个,用到的话就当个乐子就行了 注意: 因为有同学说需要IE6便做了一下. 已经处理了IE6,可测试. 腾讯的东西,感觉还好吧:) 使用方法老简单 ...

  8. Rabbitmq init terminating in do boot 问题

    其实出现这个问题的原因很简单,就是rabbitmq的安装目录中是不能带空格的,但是官方安装包会默认的将我们的程序安装到Program Files下,哭晕啊有没有.所以,我们将rabbitmq从D:\P ...

  9. PHP开发套件

    Windows系统下开发 环境配置: PHPstudy----立即下载 开发工具: PHPstorm----立即下载 引用一个注册服务器地址:潘田--phpstorm 2016.1注册码 当然推荐大家 ...

  10. windows8.1 下搭建配置apache+php+mysql

    软件版本: apache:Apache 2.4.10 Win64    http://www.apachelounge.com/download/VC11/binaries/httpd-2.4.10- ...