介绍
通过crontab 命令,我们可以在固定的间隔时间执行指定的系统指令或 shell script脚本。时间间隔的单位可以是分钟、小时、日、月、周及以上的任意组合。这个命令非常适合周期性的日志分析或数据备份等工作。
关于crontab的用途很多,如:
- 定时系统检测;
- 定时数据采集;
- 定时日志备份;
- 定时更新数据缓存;
- 定时生成报表;
-
格式
默认从左到右为:”秒 分 小时 日 月 星期几 年份”。
第1列分钟0~59
- 第2列小时0~23(0表示子夜)
- 第3列日1~31
- 第4列月1~12
- 第5列星期0~7(0和7表示星期天)
- 第6列要运行的命令
实例
* * * * * echo "hello" #每1分钟执行hello
3,15 * * * * myCommand #每小时第三分钟和第十五分钟执行
3,15 8-11 * * * myCommand# 在上午8点到11点的第3和第15分钟执行
3,15 8-11 */2 * * myCommand #每隔两天的上午8点到11点的第3和第15分钟执行
30 21 * * * /etc/init.d/smb restart #每晚的21:30重启smb
0 23 * * 6 /etc/init.d/smb restart #每星期六的晚上11 : 00 pm重启smb
// 从左往右: 秒 分 时 日 月 星期 年
"30 * * * * ? *" // 表示半分钟触发一次事件
"0 0 12 ? * WED" // 表示每个星期三中午12点
"0 0,15 8-11 * * 2" // 每周一上午8点至11点(8,9,10,11)的第0和第15分钟都触发一次事件
"0 0/5 15 * * ?" // 在每天下午3点到下午3:55期间的每5分钟触发
"0 0 12 L * ?" // 每月最后一日的中午12:00触发事件
"0 0 12 4W * ?" // 每月距离4号最近的工作日的中午12:00触发事件
"0 0 12 LW * ?" // 每月最后一个工作日的中午12:00触发事件
"0 0 12 ? * 6#3" // 每月第3个星期五中午12:00触发事件
"0 11 11 11 11 ? 2019" // 2019年的11月11号 11点11分触发(光棍节)
注意事项
新创建的cron job,不会马上执行,至少要过2分钟才执行。如果重启cron则马上执行。
当crontab失效时,可以尝试/etc/init.d/crond restart解决问题。或者查看日志看某个job有没有执行/报错tail -f /var/log/cron。
$service cron restart
使用有坑
环境变量问题
当我们刚使用crontab时,有人会告知所有命令尽量都使用绝对路径,以防错误。为什么?这就和我们下面要谈的环境变量有关了。
首先,获取控制台环境变量看下
$ env
XDG_SESSION_ID=10
HOSTNAME=localhost.localdomain
SHELL=/bin/bash
PERL_MB_OPT=--install_base /root/perl5
USER=root
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/php5/bin
PWD=/var/mail
SHLVL=1
HOME=/root
LOGNAME=root
XDG_RUNTIME_DIR=/run/user/0
_=/usr/bin/env
考虑篇幅,输出有删减。
然后,获取crontab环境变量信息
* * * * * /usr/bin/env > /tmp/env.txt
输出结果,如下
$ cat /tmp/env.txt
XDG_SESSION_ID=732
SHELL=/bin/sh
USER=root
PATH=/usr/bin:/bin
PWD=/root
LANG=de_DE.UTF-8
SHLVL=1
HOME=/root
LOGNAME=root
XDG_RUNTIME_DIR=/run/user/0
_=/usr/bin/en
对比分析两者输出
对比crontab与控制台输出,我们发现两者的环境变量差异很大。如果命令在控制台执行成功,而在crontab执行失败,我们需要考虑是否命令涉及的环境变量在crontab和控制台间存在差异。
明白crontab使用绝对路径执行命令原因了吗?
我们知道命令默认查找路径是由PATH指定的。
从上面输出结果可知,控制台的PATH值为
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/php/bin
crontab的PATH值为
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/php/bin
crontab的PATH值为
PATH=/usr/bin:/bin
/usr/local/php/bin/下面存在php命令,在控制台执行成功
$ php index.php
因在crontab的PATH变量无/usr/local/php/bin/,其执行php命令则会失败。
解决方式
已知哪个环境变量导致问题,可以直接在crontab配置中加入变量配置。
不知哪个环境变量导致问题,终极大招是引入控制台环境变量,如下
* * * * * source /$HOME/.bash_profile && command
当然,对于某特定环境变量或有特定的处理方式,如PATH,命令使用绝对路径亦可解决。