crontab定时任务详解
crontab:Unix系统中用于设置用户任务周期性调度的命令,俗称定时任务
一:语法
crontab -e #设置定时任务,用法类似vi编辑器 crontab -l #列出当前的定时任务
更多用法参考手册
/var/spool/cron/ 目录存放用户设置的定时任务,每个任务以用户创建者名字命名。比如root用户设置的定时任务,那么对应的设置文件就是:/var/spool/cron/ root
二:设置定时
设置定时分为6个字段,前面5个字段分别是:分 时 日 月 周;最后一个字段是执行命令段;如:
* * * * * php a.php #表示一分钟执行一次a.php程序
此图来源于互联网
特殊字符定义:
"*"代表所有的取值范围内的数字,如月份字段为*,则表示1到12个月;
"/"代表每一定时间间隔的意思,如分钟字段为*/10,表示每10分钟执行1次。
"-"代表从某个区间范围,是闭区间。如“2-5”表示“2,3,4,5”,小时字段中0-23/2表示在0~23点范围内每2个小时执行一次。
","分散的数字(不一定连续),如1,2,3,4,7,9。
三:实例:
* * * * * command #每分钟执行 */5 * * * * command #5分钟执行 */60 * * * * #每小时执行,注意啊,* */1 * * * 网上很多这样写是错误的,实际会每分钟都执行 10,15 * * * * command #每小时的第10和15分钟执行 10,15 9-12 * * * command #每天上午9-12点的第10和15分钟执行command 30 22 * * * /usr/local/nginx/sbin/nginx -s reload #每天22:30分重启nginx 20 8 1,10,20 * * command #每月1号,10号,20号,8:20分执行 * 20-7/1 * * * command #20点到7点,每隔1小时执行 10 9 * * 6,0 command 每周六,周日 9:10分执行
crontab最小单位是分,如果按秒执行咋办?比如一个PHP程序以10秒执行一次,介绍两种方法:
(1):在crontab中加延时执行
* * * * * sleep 10; command * * * * * sleep 20; command * * * * * sleep 30; command * * * * * sleep 40; command * * * * * sleep 50; command这里要写5个,如果是一秒执行一次,要写59个。
(2):编写shell脚本实现,脚本名称:t.sh
#!/bin/bash file="/usr/local/www/t.php" while : do fileCount=`ps -ef | grep "$file" | grep -v "grep" | wc -l` if [[ $fileCount < 1 ]]; then #判断php进程是否还在,如果不在拉起来 nohup /usr/local/php/bin/php /usr/local/www/t.php > /dev/null 2>&1 fi sleep 10 #延时10秒 done exit 0
设置一分钟执行一次
* * * * * /usr/local/t.sh #每分钟执行其实这个脚本就是个死循环,crontab每分钟触发一下脚本,不过这里会导致一个问题,如果脚本还在运行中,每分钟再触发一次,会导致系统有多个进程。
两种方式解决,1:把延时循环放在最终的脚本上,2,:加锁,这里就是t.php,在这个程序里延时。
#!/bin/bash file="/usr/local/www/t.php" fileCount=`ps -ef | grep "$file" | grep -v "grep" | wc -l` if [[ $fileCount < 1 ]]; then #判断php进程是否还在,如果不在拉起来 nohup /usr/local/php/bin/php /usr/local/www/t.php > /dev/null 2>&1 fi exit 0php中执行延时
<?php for($i=1;$i<=60; $i++){ sleep(10); echo date('h:i:s'); }
也可以再写一个shell脚本,crontab 隔一段时间执行一下该脚本,该脚本判断是否执行延时脚本。只要crontab执行的脚本中没有延时代码,一般不会出现多个进程。
我们在用加锁的方式搞一搞,这种方式更简单:flock
nohup flock -xn /usr/local/www/t.lock -c 'php /usr/local/www/t.php' > /dev/null 2>&1
-x 表示对文件加上排他锁,-n 表示文件使用非阻塞模式,-c 选项指明加锁成功后要执行的命令。以上flock 命令的整体含义就是:如果对 /usr/local/www/t.lock 文件(如果文件不存在, flock 命令会自动创建)加锁成功就执行后面的php命令,否则不执行。这样就不会有多个进程跑
开启日志
sudo vi /etc/rsyslog.d/50-default.conf cron.* /var/log/cron.log #将cron前面的注释符去掉 #重启rsyslog sudo service rsyslog restart如果修改了系统时间:
/etc/init.d/cron restart ( service cron restart )