与 Windows 上的计划任务功能类似,Linux 上也提供定时任务功能,此功能由 cron 服务进行提供。
通过 crontab
命令,可以在固定的间隔时间执行指定的系统指令或 shell script脚本。时间间隔的单位可以是分钟、小时、日、月、周及以上的任意组合。这个命令非常适合周期性的日志分析或数据备份等工作。
命令格式
crontab [-u user] file crontab [-u user] [ -e | -l | -r ]
命令参数
crontab
-u: user 用来设定某个用户的crontab服务;
file:file是命令文件的名字,表示将file做为crontab的任务列表文件并载入crontab。如果在命令行中没有指定这个文件,crontab命令将接受标准输入(键盘)上键入的命令,并将它们载入crontab。
-e:编辑某个用户的crontab文件内容。如果不指定用户,则表示编辑当前用户的crontab文件。
-l:显示某个用户的crontab文件内容,如果不指定用户,则表示显示当前用户的crontab文件内容。
-r:从/var/spool/cron目录中删除某个用户的crontab文件,如果不指定用户,则默认删除当前用户的crontab文件。
-i:在删除用户的crontab文件时给确认提示。
常用命令
重启定时任务服务
# /etc/init.d/crond restart # CentOS 6 中
# systemctl restart crond.service # CentOS 7 中
查看定时任务的日志
# tail -f /var/log/cron
小贴士:不同系列的发行版可能服务名不同,Radhat 系列 crond ,Debian 系列 cron 此处需要注意,善用自动补全。
定时任务格式
使用 more
命令即可获取格式说明
[root@test ~]# more /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
# For details see man 4 crontabs
# 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
分 时 日 月 周 要运行的命令或脚本
使用实例
实例1:每1分钟执行一次myCommand
* * * * * myCommand
实例2:每小时的第3和第15分钟执行
3,15 * * * * myCommand
实例3:在上午8点到11点的第3和第15分钟执行
3,15 8-11 * * * myCommand
实例4:每隔两天的上午8点到11点的第3和第15分钟执行
3,15 8-11 */2 * * myCommand
实例5:每周一上午8点到11点的第3和第15分钟执行
3,15 8-11 * * 1 myCommand
实例6:每晚的21:30重启smb
30 21 * * * /etc/init.d/smb restart
实例7:每月1、10、22日的4 : 45重启smb
45 4 1,10,22 * * /etc/init.d/smb restart
实例8:每周六、周日的1 : 10重启smb
10 1 * * 6,0 /etc/init.d/smb restart
实例9:每天18 : 00至23 : 00之间每隔30分钟重启smb
0,30 18-23 * * * /etc/init.d/smb restart
实例10:每星期六的晚上11 : 00 pm重启smb
0 23 * * 6 /etc/init.d/smb restart
实例11:每一小时重启smb
* */1 * * * /etc/init.d/smb restart
实例12:晚上11点到早上7点之间,每隔一小时重启smb
0 23-7 * * * /etc/init.d/smb restart
注意事项
使用定时任务的时候需要注意以下几点:
- 环境变量问题
- 日志输出问题
环境变量问题
有时我们创建了一个定时任务,但是这个任务却无法自动执行,而手动执行这个任务却没有问题,手动执行某个任务时,是在当前终端环境下进行的,程序能找到环境变量,而系统自动执行任务调度时,是不会加载任何额外环境变量的,只会读取 /etc/crontab
的环境变量,会导致很多命令无法使用,可以通过以下两种方式进行解决。
小贴士:不同系统预制的环境变量不同,Debian 系列自带的系统变量几乎涵盖了标准终端的环境变量,而 RadHat 系列只内置了 /sbin:/bin:/usr/sbin:/usr/bin 四个环境变量。
解决方式一
# 使用完整命令路径
* * * * * /usr/sbin/ntpdate ntp1.aliyun.com
解决方式二
# 将命令写入脚本,在脚本中引入环境变量
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
export PATH
日志输出问题
每条任务调度执行完毕,系统都会将命令的输出信息通过电子邮件的形式发送给当前系统用户,这样日积月累,日志信息会非常大,可能会影响系统的正常运行,因此将每条命令进行重定向处理非常重要。
0 */3 * * * /usr/local/apache2/apachectl restart >/dev/null 2>&1
小贴士:/dev/null 2>&1
表示先将标准输出重定向到/dev/null
,然后将标准错误重定向到标准输出,由于标准输出已经重定向到了/dev/null
,因此标准错误也会重定向到/dev/null
,这样就不会输出任何日志。
>/dev/null 2>&1
等价于 &>/dev/null
补充信息
MTA 报错问题
在 Debian & Ubuntu 下使用定时任务,会发现日志文件中存在大量报错信息。
Jan 23 23:20:01 ubuntu CRON[19804]: (CRON) info (No MTA installed, discarding output)
这是因为定时任务的日志都是默认发送至邮件服务以邮件形式传送,因此在部分最小化安装的系统中没有邮件服务导致的。
# apt install postfix
安装邮件服务即可。
日志文件丢失
在 Debian & Ubuntu 下使用定时任务,会发现日志文件没有单独生成(/var/log/cron.log
),而是与系统日志(/var/log/syslog
)写入到一起了。
要拆分定时任务日志,其实是系统日志配置问题,修改 rsyslog 配置文件,取消 cron.log 前的注释即可。
$ sudo vim /etc/rsyslog.d/50-default.conf
然后注意重启定时任务服务和日志服务。
$ sudo systemctl restart rsyslog cron
时间精度问题
在定时任务中,最小的时间粒度是分钟 min ,但是实际使用中,部分程序或者功能需要以秒钟为粒度,定时任务其实可以实现此功能。
* * * * * sleep 10; /usr/bin/curl http://localhost/index.php
* * * * * sleep 20; /usr/bin/curl http://localhost/index.php
* * * * * sleep 30; /usr/bin/curl http://localhost/index.php
* * * * * sleep 40; /usr/bin/curl http://localhost/index.php
* * * * * sleep 50; /usr/bin/curl http://localhost/index.php
小贴士:实际上定时任务还是每分钟执行一次,但是因为设置了五条定时任务,且每条之前都睡眠了十秒,因此可以实现每隔几秒执行一次。
其他注意事项
- 当定时任务失效时,可以尝试重启定时任务进程或检查日志排查命令执行情况;
- 更新系统时间时区后需要重启进程才能正常生效;
- 不要随意执行
crontab -r
。会从crontab目录(/var/spool/cron)中删除用户的全部定时任务; - 在定时任务命令中
%
是有特殊含义的,表示换行的意思,如果要用的话必须进行转义\%
; - 最好在定时任务每条之上加入注释,标注上执行用户、执行时间、功能(尽量使用英文标注,以防他人连接显示乱码)。
附录
参考链接
本文由 柒 创作,采用 知识共享署名4.0
国际许可协议进行许可。
转载本站文章前请注明出处,文章作者保留所有权限。
最后编辑时间: 2018-06-27 15:45 PM