最近意外发现crontab 的时间day_of_month和day_of_week是不能同时起作用的,或者说不是我想象中的and的关系,而是or的关系。例如:要实现定时执行data>/opt/tmpFile/testCrontab命令,在每个月的1~13号的周1,2,4,5的早上8点和周2的晚上8点执行命令。
先简单介绍下crontab命令:
crontab是一个命令,常见于Unix和类Unix操作系统中,用于设置周期性被执行的命令。而crond是它的守护进程。当安装完操作系统后默认会安装此服务工具并且会自动启动crond,该进程会每分钟定期检查是否有要执行的任务,若有则执行。
在使用crontab之前必须确保crond服务是开启的!
service crond start #启动服务
service crond stop #关闭服务
service crond restart #重启服务
service crond reload #重新载入配置
Linux下的任务调度分为俩种:系统任务调度和用户任务调度
-》系统任务调度,其配置文件为/etc/crontab
-》用户任务调度
首先要知道几个目录文件:
/etc/cron.deny #该文件中所列用户不允许使用crontab命令
/etc/cron.allow #该文件中所列用户允许使用crontab命令
/var/spool/cron/ #所有用户crontab文件存放的目录,以用户名命名
其次关于crontab的命令参数:
crontab [-u user] file
crontab [-u user] [ -e | -l | -r ]
注:
-u user:用于设定某个用户的crontab,此参数一般由root来运行,不指定的默认情况下是当前登陆的用户
file:是命令文件的名字,表示file作为crontab的任务列表文件并载入crontab,若未指定将接受键盘上键入的命令
-e:进入当前用户的定时任务文件编辑模式
-l:显示当前用户的定时任务文件
-r:删除当前用户的crontab文件,也可-u删除指定用户的
-i:在删除用户crontab文件时给确认提示
设置定时任务有俩种方式,从命令格式也可以看出来,一种是通过添加file的方式,一种是直接-e直接进入编辑模式。
-->crontab file:
先编写cron脚本,例如命名为testFile.cron,脚本内容的格式和/etc/crontab文件给出注释格式一样;
执行crontab testFile.cron;
最后可通过crontab -l 或 /var/spool/cron是否生成对应的脚本或是否有成功在规定时间内执行进行验证。
-->crontab -l:
直接进入该用户的编辑文件,进行定时任务编辑。
-》定时任务编辑格式:
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
在五个*的位置用来表示时间,除了以上注释标注的数字可以填入,还可搭配符号一起:
# 星号(*):代表所有可能的值
# 逗号(,):可以用逗号隔开的值指定一个列表范围,eg:"1,3,5,7,9"
# 中杠(-):可以用整数之间的中杠表示一个整数范围,eg:"1-5",即表示"1,2,3,4,5"
# 正斜线(/):可以用正斜线指定时间的间隔频率,eg:"*/10"表示分钟的话即每十分钟执行一次
关于crontab的基本先介绍到这里,后续在使用中碰到的问题再深入讨论。
下面继续回答开篇的问题:要实现定时执行data>/opt/tmpFile/testCrontab命令,在每个月的1~13号的周1,2,4,5的早上8点和周2的晚上8点执行命令。
想当然的去写:
* 8 1-13 * 1,2,4,5 data>/opt/tmpFile/testCrontab
是达不到想要的效果,因为day_of_month 和 day_of_week 同时设置的情况下是or的关系,即会出现这样的情况,每个月的1~13号会执行和所有的周1,2,4,5都会执行这条命令,显然这不是我们想要的结果。
我的想法以及处理方法是,将命令data>/opt/tmpFile/testCrontab单独写到一个脚本里面去,eg:run_data.sh,并在这个脚本里面加上对时间的判断:
#判断星期: Mon|Tue|Wed|Thu|Fri|Sat|Sun ->周二早上晚上执行,周一四五早上执行,其他day_of_week不执行
day_of_week=Tue
case $day_of_week in
Tue)
#echo "Tue)"
week_flag=true
;;
Mon|Thu|Fri)
#echo "Mon|Thu|Fri)"
stop=11
if [ $hour -le $stop ]
then
week_flag=true
fi
;;
*)
echo "nothing to do"
;;
esac
然后在crontab里面执行这个脚本:
* 8 1-13 * * sh run_data.sh
若有说错或理解错误的地方,烦请指正!!