第十七章:第45节Linux 定时任务crontab(用户任务调度)

更新于:2019-02-01 13:50:36

这节我们学习一个非常有用的功能——定时任务。就是设定某个时间预备做什么事,时间一到就会自动执行。这个功能超实用的!单说web应用,只有在用户访问我们的网站时,才会触发PHP脚本。假如说有这样的功能,给所有的用户发新年礼物,预定时间在1月1日凌晨0点0分。发礼物的逻辑有PHP脚本完成,只需要在1月1日凌晨0点0分触发执行脚本即可。假如说没有Linux的定时任务帮忙触发脚本,那只有依靠我们手动去触发了。我们守着点,时间一到访问下特定页面即可。楠神觉着这样也太low了,机器能干的活干嘛浪费人力资源去干,人力干出得效果还不好。


定时任务——crontab


定时任务——crontab,其实就是一个守护进程。我们书写好各种任务规则,每过一分钟crontab就去检查下有没有要执行的规则(即各种命令)。


在Ubuntu 9.10下,cron(crontab进程名)是默认安装并启动的。

1.png


1)打开规则编辑器


crontab -e

使用crontab命令打开规则编辑器


1.png


第一次打开,需要选择一款编辑器。我们选择3


后期更改编辑器执行命令:

select-editor


打开后内容是这样的:

1.png


一行即一个规则


2)书写规则


每一行都代表一项任务,每行的每个字段代表一项设置,它的格式共分为六个字段,前五段是时间设定段,第六段是要执行的命令段,格式如下:

minute   hour   day   month   week   command

其中:

minute: 表示分钟,可以是从0到59之间的任何整数。

hour:表示小时,可以是从0到23之间的任何整数。

day:表示日期,可以是从1到31之间的任何整数。

month:表示月份,可以是从1到12之间的任何整数。

week:表示星期几,可以是从0到7之间的任何整数,这里的0或7都代表星期日

command:要执行的命令,可以是系统命令,也可以是自己编写的脚本文件。


1.png


在以上各个字段中,还可以使用以下特殊字符:

星号(*):代表所有可能的值,例如month字段如果是星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。

逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9”

中杠(-):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6”

正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。同时正斜线可以和星号一起使用,例如*/10,如果用在minute字段,表示每十分钟执行一次。


3)演示


添加规则:

*/1 * * * * php /root/crontab.php

意思每过一分钟执行一次crontab.php脚本

1.png

保存后

1.png


自动写入/var/spool/cron/crontabs/<username>(或者/var/spool/cron/<username>)


cd /var/spool/cron/crontabs

1.png

可查看root用户的定时任务列表。此时定时任务已生效,也不需要重启cron服务。


②创建PHP脚本


1.png


③去看下PHP脚本有没有执行成功


1.png


OK,成功了。


4)crontab命令其他参数


crontab -u user

用来设定某个用户的crontab服务,例如,“-u nanshen”表示设定nanshen用户的crontab服务,此参数一般有root用户来运行。


crontab filename

filename是命令文件的名字,表示将file做为crontab的任务列表文件并载入crontab。如果在命令行中没有指定这个文件,crontab命令将接受标准输入(键盘)上键入的命令,并将它们载入crontab。


crontab -e

编辑某个用户的crontab文件内容。如果不指定用户,则表示编辑当前用户的crontab文件。


crontab -l

显示某个用户的crontab文件内容,如果不指定用户,则表示显示当前用户的crontab文件内容。


crontab -r

从/var/spool/cron目录中删除某个用户的crontab文件,如果不指定用户,则默认删除当前用户的crontab文件。


crontab -i

在删除用户的crontab文件时给确认提示。


5)防误删,常做备份


crontab -r

会清空定时任务,一般很容易误操作(因为r键紧挨在e键的右边)。所以定时任务要常做备份。


备份命令:

crontab -l > $HOME/mycron

备份到主目录。


楠神在本章第六节《Linux目录与文件——文件操作》讲“echo”命令时,“>”表示把显示的内容添加到文件。“>”在上面的命令中也适用。


$HOME是环境变量。


1.png


备份成功。


需要恢复时,把备份文件拷贝到/var/spool/cron/crontabs/<username>(或者/var/spool/cron/<username>),其中<username>是用户名。

如果由于权限问题无法完成拷贝,可以用:

crontab <filename>

其中,<filename>是你在$ H O M E目录中副本的文件名。


6)注意环境变量问题


有时我们创建了一个crontab,但是这个任务却无法自动执行,而手动执行这个任务却没有问题,这种情况一般是由于在crontab文件中没有配置环境变量引起的。


在crontab文件中定义多个调度任务时,需要特别注意的一个问题就是环境变量的设置,因为我们手动执行某个任务时,是在当前shell环境下进行的,程序当然能找到环境变量,而系统自动执行任务调度时,是不会加载任何环境变量的,因此,就需要在crontab文件中指定任务运行所需的所有环境变量,这样,系统执行任务调度时就没有问题了。


不要假定cron知道所需要的特殊环境,它其实并不知道。所以你要保证在shell脚本中提供所有必要的路径和环境变量,除了一些自动设置的全局变量。所以注意如下3点:


①脚本中涉及文件路径时写全局路径;


②脚本执行要用到java或其他环境变量时,通过source命令引入环境变量,如:

cat start_cbp.sh
#!/bin/sh
source /etc/profile
export RUN_CONF=/home/d139/conf/platform/cbp/cbp_jboss.conf
/usr/local/jboss-4.0.5/bin/run.sh -c mev &


③当手动执行脚本OK,但是crontab死活不执行时。这时必须大胆怀疑是环境变量惹的祸,并可以尝试在crontab中直接引入环境变量解决问题。如:

0 * * * * ./etc/profile;/bin/sh /var/www/java/audit_no_count/bin/restart_audit.sh


7)cron服务的操作


通过上节的内容,大体我们也能猜出cron服务的开启、关闭、重启操作命令为:


1.png


service cron start     开启
service cron stop      关闭
service cron restart   重启


8)通过web访问执行PHP脚本


上面做的一个示例直接使用的PHP解释器执行的PHP脚本。通常我们写的PHP脚本是放到web服务器中执行的,假如一个定时任务需要通过web访问的方式执行PHP脚本,那该怎么做?


服务器上需要安装一个有web请求功能的服务。推荐:lynx。


1.png


lynx命令 是纯文本模式的网页浏览器,不支持图形、音视频等多媒体信息。


apt-get install lynx            安装
lynx -dump http://www.xxx.com   web请求


添加定时任务:

0 */1 * * * lynx -dump https://www.phpnanshen.com/home/crontab/index

每小时请求一次https://www.phpnanshen.com/home/crontab/index。


结:


有了crontab,我们的网站也可以做各种定时执行的功能。同时,crontab还有个重要的用处,用它每天定时备份数据库到指定的数据盘(自己搜索下Linux导出数据库数据的命令)。


Linux下的任务调度分为两类,系统任务调度用户任务调度


这节楠神所讲的是用户任务调度。顾名思义,每个登录的用户,都可以使用crontab -e命令为自己设置计划任务。


打开/etc/crontab文件:


1.png


在这个文件中,也可以添加定时任务。


1.png


看其权限,只有root用户可以修改。在这个文件中添加的定时任务就是系统任务调度。


系统任务调度不讲了,大家看下这篇分享的文章《/etc/crontab文件和crontab -e命令区别


/var/log下有cron的日志文件,假如没有?


去修改rsyslog配置文件

vi /etc/rsyslog.d/50-default.conf (ubuntu)
vi /etc/rsyslog.conf (centos)

将  rsyslog  文件中的  #cron.*  前的  #  删掉;


重启rsyslog服务

service rsyslog restart


重启cron服务

service cron restart

这样就可以了。


如果还没有,可能和权限有关系,看这篇文章就知道怎么回事了《/var/log/auth.log文件不存在


auth.log日志频繁生成cron日志内容的处理方法:《禁止Cron: pam_unix写入auth.log日志


crontab日志显示:(CRON) info (No MTA installed, discarding output)