【shell】防止脚本重复运行

来源:互联网 发布:java工程师具备的能力 编辑:程序博客网 时间:2024/05/16 09:00

有些业务脚本需要防止重复,以便造成业务数据不一致。

所以,一般在脚本运行开始,就首先要检查当前系统是否有该脚本的运行进程。

一般人多半是这样写的(比如我们系统里的那帮人):

processName="OMIGet_HOUR.sh"processNum=`ps -aef |grep "${processName}" | wc -l`if [ "${processNum}" -gt "3" ]; then  echo "已经有脚本在运行,本脚本不支持多实例运行${processNum}"  exit 1fi

这样写有个问题,是什么呢?

ps -ef  | grep 的返回结果在是否包含grep时具有不确定性(可以加上-v参数避免,但很麻烦)。所以稍不注意,判断就会失败。

其实我们可以使用更安全的一种方式来判断,如:

#!/bin/kshRUNDIR=`dirname $0`PIDFILE="${RUNDIR}/$0.pid"if [ -s ${PIDFILE} ]; then  echo "脚本已经在运行,不重复运行,退出."  exit 1fiecho $$ > ${PIDFILE}<各种业务处理逻辑>cat /dev/null > ${PIDFILE}
借助pidfile来判断,脚本在运行之初判断是否有进程号即可。

当然,如果脚本在运行之中被强制kill掉,那么下次怎么也运行不起来了。

不过这个问题,我们可以这样来解决:在脚本“假退出”之前,通过各种告警来提示维护人员(以手工介入处理)。


网上有很多关于在shell执行文件本身通过flock的命令加锁来实现互斥的方式,个人觉得,该方法不具有自助可控性,风险较大,最重要的是不具有平台通用性。

所以更加推荐如下方式:

#!/bin/kshRUNDIR=`dirname $0`PIDFILE="${RUNDIR}/$0.pid"if [ -s ${PIDFILE} ]; then   SPID=`cat ${PIDFILE}`   if [ -e /proc/${SPID}/status ]; then      echo "脚本已经在运行,不重复运行,退出."      exit 1  fi  cat /dev/null > ${PIDFILE}fiecho $$ > ${PIDFILE}#各种业务逻辑cat /dev/null > ${PIDFILE}

经过测试,该方法能够表现良好。

1 0
原创粉丝点击