shell crontab
编程技术  /  houtizong 发布于 3年前   168
#/bin/bash## @function shell crontab # @author liuniuyou# @version 0.1# @date 2014-12-30##CREATE TABLE `task` (#`task_name` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '任务名称' ,#`description` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0' COMMENT '任务描述' ,#`bin` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '执行程序' ,#`script` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '执行脚本' ,#`args` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0' COMMENT '脚本参数 多个参数加:间隔' ,#`cycle` enum('6','5','4','3','2','1') CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '执行周期 1周 2分 3小时 4 天 5 月 6年 ' ,#`start_day` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '0' COMMENT '数据库 默认值为0 表示 日期为空不设置' ,#`start_time` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '开始执行时间 因为开始 时间 有些为天 有些 为时 不统一用字符' ,#`times` int(11) NOT NULL COMMENT '次数' ,#`intervall` int(10) UNSIGNED NULL DEFAULT NULL COMMENT '间隔时间' ,#`pid` int(11) NULL DEFAULT NULL COMMENT '执行程序的pid 如果多个加:间隔' ,#`count` int(11) NULL DEFAULT 0 COMMENT '本cycle 执行周期内 已经运行的次数。运行完清零' ,#`exec_time` int(11) NULL DEFAULT 0 ,#PRIMARY KEY (`task_name`)#)#ENGINE=MyISAM#DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci#CHECKSUM=0#ROW_FORMAT=DYNAMIC#DELAY_KEY_WRITE=0#;. /taskcron/common/commonexportEnvTABLE="yt_task"RUNBYYEAR=6RUNBYMONTH=5RUNBYDAY=4RUNBYHOUR=3RUNBYMINUT=2RUNBYWEEK=1MUSTRUN=1GIVEUPRUN=0EXISTPID=1NOEXISTPID=0 scriptPid=$$#$1 cycle#$2 starttimegetLastCycleDetail(){ starttime=$2 cycleTime=$1 nowTimestamp=`date +%s` dayTimestamp=$[$nowTimestamp-$cycleTime] lastCycleTime=`echo $dayTimestamp|awk '{print strftime("%Y:%m:%d:%T",$0)}'` lDayY=`echo $lastCycleTime|awk -F":" '{print $1}'` lDayM=`echo $lastCycleTime|awk -F":" '{print $2}'` lDayD=`echo $lastCycleTime|awk -F":" '{print $3}'` lDayH=`echo $lastCycleTime|awk -F":" '{print $4}'` lDayF=`echo $lastCycleTime|awk -F":" '{print $5}'` lDayS=`echo $lastCycleTime|awk -F":" '{print $6}'` case $cycle in "$RUNBYYEAR") lastStartTimestamp=`date -d "${lDayY}-$starttime" +%s` ;; "$RUNBYMONTH") lastStartTimestamp=`date -d "${lDayY}-${lDayM}-$starttime" +%s` ;; "$RUNBYDAY") startTime=`echo $2|awk -F" " '{print $2}'` lastStartTimestamp=`date -d "${lDayY}-${lDayM}-${lDayD} $startTime" +%s` ;; "$RUNBYHOUR") lastStartTimestamp=`date -d "${lDayY}-${lDayM}-${lDayD} ${lDayH}:$starttime" +%s` ;; "$RUNBYMINUT") lastStartTimestamp=`date -d "${lDayY}-${lDayM}-${lDayD} ${lDayH}:${lDayF}:$starttime" +%s` ;; "$RUNBYWEEK") weekDay=`echo $starttime|awk -F" " '{print $1}'` startTime=`echo $starttime|awk -F" " '{print $2}'` lastStartTimestamp=`date -d "${lDayY}-${lDayM}-${lDayD} $startTime" +%s` ;; *) ;; esac}getNowDetail(){ now=`date +"%Y:%m:%d:%H:%M:%S"` nowTimestamp=`date +%s` nowY=`echo $now|awk -F":" '{print $1}'` nowM=`echo $now|awk -F":" '{print $2}'` nowD=`echo $now|awk -F":" '{print $3}'` nowH=`echo $now|awk -F":" '{print $4}'` nowF=`echo $now|awk -F":" '{print $5}'` nowS=`echo $now|awk -F":" '{print $6}'` nowW=`date +%w`}# $1 cycle # $2 Startime # $3 intervall 间隔时间# $4 times 要运行的次数# $5 count 已经运行的次数# $6 lastExecStampisToExeTime(){ getNowDetail case $1 in "$RUNBYYEAR") startTimestamp=`date -d "${nowY}-$2" +%s` #isExecByYear "$2" "$3" "$4" "$5" ;; "$RUNBYMONTH") startTimestamp=`date -d "${nowY}-${nowM}-$2" +%s` ;; "$RUNBYDAY") startTime=`echo $2|awk -F" " '{print $2}'` startTimestamp=`date -d "${nowY}-${nowM}-${nowD} $startTime" +%s` ;; "$RUNBYHOUR") startTimestamp=`date -d "${nowY}-${nowM}-${nowD} ${nowH}:$2" +%s` ;; "$RUNBYMINUT") startTimestamp=`date -d "${nowY}-${nowM}-${nowD} ${nowH}:${nowF}:$2" +%s` ;; "$RUNBYWEEK") weekDay=`echo $2|awk -F" " '{print $1}'` startTime=`echo $2|awk -F" " '{print $2}'` # 按周的不等于就放弃 如周二运行 必须周二运行 if [ ${weekDay} -ne ${nowW} ];then return $GIVEUPRUN fi startTimestamp=`date -d "${nowY}-${nowM}-${nowD} $startTime" +%s` ;; *) ;; esac # 此处不存在 times 与 count 相等的处理,此逻辑在updateTaskCount函数中处理。 $lastExecStamp都为 前次处理的时间戳了 所以只要加一次间隔时间就可以了。 # ${count}为0 次运行 不需要加间隔时间。只需要判断startTimestamp 时间 count=$5 lastExecStamp=$6 runTimestamp=$[$lastExecStamp+$3] writeLog "count ${count} nowTimestamp ${nowTimestamp} runTimestamp ${runTimestamp} startTimestamp ${startTimestamp} " if [ ${nowTimestamp} -lt ${startTimestamp} ];then return $GIVEUPRUN else if [ $count -eq 0 ];then if [ $lastExecStamp -lt $startTimestamp ];then return $MUSTRUN else return $GIVEUPRUN fi fi fi if [ ${nowTimestamp} -lt ${runTimestamp} ];then return $GIVEUPRUN else return $MUSTRUN fi}# $1 cycle # $2 taskName# $3 starttime# $4 allIntervallupdateTaskCount(){ nowStamp=`date +%s` cycle=$1 starttime=$3 taskIntvall=$4 cycleDiff=0 case $cycle in "$RUNBYYEAR") cycleDiff=$[365*24*3600] ;; "$RUNBYMONTH") cycleDiff=$[31*24*3600] ;; "$RUNBYDAY") cycleDiff=$[24*3600] ;; "$RUNBYHOUR") cycleDiff=3600 ;; "$RUNBYMINUT") cycleDiff=60 ;; "$RUNBYWEEK") cycleDiff=$[7*24*3600] ;; *) ;; esac getLastCycleDetail "$cycleDiff" "$starttime" diff=$[$nowStamp-$lastStartTimestamp] writeLog "updateCount:lastStartTimestamp $lastStartTimestamp starttime $3 allIntervall $4 nowStamp ${nowStamp} diff-${diff} cycleDiff ${cycleDiff} " if [ ${diff} -gt ${cycleDiff} ];then writeLog "任务 $2 开始新的周期,更新计数器"updateCount=`mysql -u$USER -p$PASSWORD $DATABASE<<EOFUPDATE $TABLE SET count=0,exec_time='$nowStamp' WHERE task_name='$2';exit EOF`>/dev/null else writeLog "任务 $2 本周期内所有任务已经完成,还未到新周期的开始,等待中..... " fi}#$1 数字# 是数字 返回 1checkInt(){ if echo $1 | egrep -q '^[0-9]+$'; then echo 1 else echo 0 fi}#$1 taskname #$2 CMD 运行的命令脚本#$3 count 已经运行的次数#$4 times 计划运行次数#$5 PidexecCmd(){ writeLog " 任务 $1 的 pid: $5 count $3 times $4 taskName $1 CMD $2 " pidIsNUll=`checkInt "$5"` writeLog "pidIsNUll $pidIsNUll" if [ $pidIsNUll -gt 0 ];then isRun=`exsitPid $5` else isRun=$NOEXISTPID fi writeLog "ps -a | grep "$5" | wc -l " writeLog "isRun :$isRun " if [ "$isRun" = "$EXISTPID" ];then writeLog "任务 $1 已经有进程在运行 " else writeLog "CMD: $2" CMD="$2" eval "$CMD" >> /dev/null & pid=$! execTime=`date +%s` #`date +"%Y-%m-%d:%H:%M:%S"` writeLog "execCmd count:$count" #更行pid 和 count count=$3 if [ ${times} -gt ${count} ];then count=$[${count}+1] fi writeLog "execCmd2 count:$count" writeLog "CMD $2 UPDATE $TABLE SET count='${count}',pid=$pid,exec_time='$execTime' WHERE task_name='$1'; " updateCount=`mysql -u$USER -p$PASSWORD $DATABASE<<EOFUPDATE $TABLE SET count='$count',pid=$pid,exec_time='$execTime' WHERE task_name='$1';exitEOF`>/dev/null writeLog "update pid exec_time: $updateCount" writeLog "任务 $1 命令 $2 本周期已经运行 $3, 现在开始运行第$count次 ..... " fi}exsitPid(){ echo `ps -a | grep "$1" | wc -l`}writeLog "taskcron 主进程pid ${selfPid}"##初始化时间点 2015-01-01 00:00:00 即时间戳1420041600`mysql -u$USER -p$PASSWORD $DATABASE<<EOFUPDATE $TABLE SET exec_time='1420041600',count=0EOF`while :doscript=`basename $0`day=`date +"%Y%m%d%H"`LogFile="/taskcron/log/"${day}"_"${script}".log"if [ ! -d "/taskcron/log/" ]then mkdir /taskcron/log/ chmod -R 777 /taskcron/log/fideclare -a recordsrecords=`mysql -u$USER -p$PASSWORD $DATABASE<<EOF | tail -n +2SELECT task_name,bin,script,IFNULL(args,0),cycle,IFNULL(start_day,0),IFNULL(start_time,0),times,intervall,IFNULL(pid,0),IFNULL(count,0),IFNULL(exec_time,0),'||' as split FROM $TABLE;exitEOF`>/dev/nulli=1taskLines=${records}for field in ${taskLines[@]} do if [ "$field" = "||" ];then #如果本周期的运行次数已经完成 退出循环 if [ ${times} -eq ${count} ];then #当前时间为周期时间的结尾 则更新计数器 allInteravall=$[${times}*${intervall}] updateTaskCount "$cycle" "$taskName" "$startTime" "$allInteravall" i=1 CMD="" writeLog "*****************任务 单次 $taskName end*********************" continue writeLog "continue ...." fi if [ "${startDay}" != "0" ];then startTime=$startDay" "$startTime fi isToExeTime "$cycle" "$startTime" "$intervall" "$times" "$count" "$lastExecTime" runFlag=$? if [ ${runFlag} -eq ${MUSTRUN} ];then execCmd "$taskName" "$CMD" "$count" "$times" "$pid" else writeLog "间隔时间为 $intervall, 本次运行时间还没有到!等待中..... " fi i=1 CMD="" writeLog "*****************任务单次 $taskName end*********************" else case $i in "1") taskName="$field" writeLog "*****************任务单次 $taskName start*********************" ;; "2") CMD="$field" ;; "3") CMD="$CMD $field" ;; "4") args=`echo "$field"|sed -r "s/:/ /g"` CMD="$CMD $args" ;; "5") cycle=$field ;; "6") startDay="$field" ;; "7") startTime="$field" ;; "8") times="$field" ;; "9") intervall="$field" ;; "10") pid="$field" ;; "11") count="$field" ;; "12") lastExecTime="$field" ;; *) ;; esac let "i=$i+1" fi done sleep 1sdone
请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!
技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成
网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];
文章归档
文章标签
友情链接