10秒間隔にジョブを実行する

当時間間隔にジョブ(drop_jobを想定)を実行する方法として、下記の方法などがよく紹介されています。

#!/bin/bash

while true

do

 sleep 10

 ./drop_job

done 

 これだとdrop_jobが終了した時点から10秒後に次のdrop_jobが再会されます。ですから、例えば

# drop_jobの中身
echo 現在時刻は `date +"%F %T"` です
sleep 5

みたいに、それ自体が時間のかかるジョブだと10秒間隔で実行できません。

manページで見ると、atコマンドに-tオプションを指定すると秒単位まで開始時刻を指定できるみたいなのですが、実際にはこれもうまく行きませんでした。

仕方がないのでC言語で作成してみました。C言語なんて使ったの何年ぶりだろ…。

プログラム名をinterval_jobとして、

 interval_job interval=[実行間隔] job=[実行コマンド] end=[終了日時]

で使用します。終了日時は省略可です。

 今のところ問題なく使用できているようです。

 

f:id:S_E_Hyphen:20171102161306p:plain

 

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<time.h>

void conv_date(time_t time, char *s);
void conv_datetime(time_t time, char *s);
time_t set_time(int year, int month, int day, int hour, int min, int sec);
int usage();
int getparint(int argc, char **argv, char *str, int *ptr);
int getparfloat(int argc, char **argv, char *str, float *ptr);
int getparstr(int argc, char **argv, char *str, char *ptr);

/***************** self documentation *********************/
char sdoc[20][80] = {
" ",
" interval_job 等しい秒間隔にジョブを投入する ",
" option: ",
" interval= 実行間隔(秒) ",
" job= 実行するコマンド(80文字以内) ",
" end= 終了日時(YYYY-MM-DD hh:mm:ss) ",
" "};
/***************** end self doc ***************************/

main(int argc, char **argv)
{
int interval;
char job[80];
time_t now,base,end;
char datetime[30],endtime[30];
int year,month,day;
int hour,min,sec;
if(!getparint(argc,argv,"interval",&interval))usage();
if(!getparstr(argc,argv,"job",job))usage();
if(!getparstr(argc,argv,"end",endtime))sprintf(endtime,"2038-01-18 23:59:59");
sscanf(endtime,"%4d-%2d-%2d %2d:%2d:%2d",&year,&month,&day,&hour,&min,&sec);
end=set_time(year,month,day,hour,min,sec); // 終了日時のtime_tを取得

time(&base); // 開始日時のtime_tをbaseとする
while(base<end)
{
while(now<base){time(&now);} //ここがタイマー
system(job); // ループを抜けたらジョブを実行
base+=interval;
}

}

void conv_date(time_t time, char *s)
{
struct tm *lst;
lst=localtime(&time);
strftime(s,256,"%Y-%m-%d",lst);
}

void conv_datetime(time_t time, char *s)
{
struct tm *lst;
lst=localtime(&time);
strftime(s,256,"%Y-%m-%d %H:%M:%S",lst);
}

time_t set_time(int year, int month, int day, int hour, int min, int sec)
{
struct tm tm_ptr;
tm_ptr.tm_year = -1900 + year;
tm_ptr.tm_mon = -1 + month;
tm_ptr.tm_mday = day;
tm_ptr.tm_hour = hour;
tm_ptr.tm_min = min;
tm_ptr.tm_sec = sec;
if(mktime(&tm_ptr)==(time_t)-1)
{
fprintf(stderr,"NG! set_time\n");
} else {
return(mktime(&tm_ptr));
}
}


int usage()
{
int i;
for(i=0;i<20;i++)
fprintf(stderr,"%s\n",sdoc[i]);
exit(1);
}
int getparint(int argc, char **argv, char *str, int *ptr)
{
int i,len;
char s1[50];
len=strlen(str)+1;
for(i=1;i<argc;i++)
{
if(!strncmp(str,*(argv+i),strlen(str)))
{
strcpy(s1,*(argv+i));
sscanf(s1+len,"%d",ptr);
return(1);
}
}
return(0);
}
int getparfloat(int argc, char **argv, char *str, float *ptr)
{
int i,len;
char s1[50];
len=strlen(str)+1;
for(i=1;i<argc;i++)
{
if(!strncmp(str,*(argv+i),strlen(str)))
{
strcpy(s1,*(argv+i));
sscanf(s1+len,"%f",ptr);
return(1);
}
}
return(0);
}
int getparstr(int argc, char **argv, char *str, char *ptr)
{
int i,len;
char s1[50];
len=strlen(str)+1;
for(i=1;i<argc;i++)
{
if(!strncmp(str,*(argv+i),strlen(str)))
{
strcpy(s1,*(argv+i));
strcpy(ptr,s1+len);
return(1);
}
}
return(0);
}