在这一章当中我们讲述Linux任务计划以及周期性任务的执行。
一、任务计划
我们此前说过一些备份的知识,假如在某种场景当中需要做备份,例如MySQL、Redis以及mongodb等数据管理系统或相关服务及程序,对于那些数据而言,如果要做周期备份的话,则必然就要用到该功能。在例如,对于公司来讲,最关键的就是数据,而不是系统,因为只要数据还在,则可以快速建立一个系统,而如果数据不在,则无法建立出系统。所以数据备份是至关重要的一件事情。
数据备份通常每天一次,甚至于每小时一次,那么这种任务我们就称之为是周期性任务。还有一种就是在凌晨的时候,把某个目录一次性给复制到另一台备份主机,如果这是周期性质的话,每天做一遍,那这就是周期性任务,如果说是为了每个需要,只是做一次的话,那这种就是任务计划。
他俩的本质没有太大的差别,有一些区别的就是一种在未来的某一个时间点执行一次任务,另一种就是重复或周期性运行某任务,总结如下:
未来的某时间点执行一次某任务:at, batch 周期性运行某任务:crontab 执行结果:会通过邮件发送给用户;
对于Linux来讲,周期性任务是要经常执行的,而单一的任务计划也是需要在未来的某一时刻进行运行,如果用户没有登录在线的话,一旦任务执行完成,会通过邮件来发送给用户。这种电子邮件并不需要连接到互联网中,而是在本地系统上会启用一个邮件服务,这个服务只能用于本地用户与用户之间彼此传递信息。这种用户不在线时将执行结果通过邮件发送给用户,是一种非常行之有效的方式,这种邮件服务并不是并不是互联网那种公开的服务,而是仅仅保证本地用户在下一次登录时的,该邮件执行的是推送消息结果的服务,所以说这个服务只能用于本机上来相互传递邮件消息。但如果要想工作起来,需要依赖两点,第一就是要启动该邮件服务,第二点就是有该用户临时的收发位置,不过好在CentOS
中,默认都是开启本地邮件服务,我们可以用netstat
或者ss
命令来查看某个服务25号端口是否开启。
# ss -tnl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 100 ::1:25 :::*
可以看出,25号端口处于监听开启状态,如果该端口开启的话,就说明服务运行正常。那么查看某个端口的命令如下:
# netstat -tnlp # ss -tnl
1.1 mailx命令
为了能查看任务往来的通信结果及情况,我们需要前提掌握关于邮件的收发命令,否则无法判断该任务计划到底执行与否,所以我们来查看本地电子邮件服务。
本地电子邮件服务: smtp:simple mail transmission protocol pop3:Post Office Protocol imap4:Internet Mail Access Protocol
以上的几种协议了解即可,我们现在主要掌握的是如何在本地主机上收发邮件,其该命令为mail命令。它能够收发互联网邮件,是一个很强大的文本行界面的工具,它是一种用户收发邮件的一种工具程序,我们称之为MUA,不管是WEB界面上的还是字符界面上的,我们都称之为用户收发的一种工具程序。
要想使用mail或mailx命令收发邮件的话,方法是很简单的,该命令的格式为:
mail命令: mailx - send and receive Internet mail MUA: Mail User Agent,用户收发邮件的工具程序; mailx [-s 'SUBJECT'] username[@hostname]
比如说,写一个邮件发送给abc3用户,指明主题为'hello wuhuang!'
# mail -s 'hello wuhuang' abc3
我们看到,底下有一行空白处,这是系统等待用户输入内容后,按.
进行单独一行发送,邮件发送完成。所以说该命令是这样的。
# mail -s 'hello wuhuang' abc3 wuhuangwansui! . EOT
之后我们切换abc3,使用mail命令查看邮件是否存在,需要注意的是,mail不带任何选项是收邮件及查看邮件的,N表示为新邮件,按相关序号就能进行查看,那么看完之后按q
键退出。
# su - abc3 $ mail Heirloom Mail version 12.5 7/5/10. Type ? for help. "/var/spool/mail/abc3": 1 message 1 new >N 1 root Sat Mar 10 19:43 18/580 "hello wuhuang" & 1 Message 1: From [email protected] Sat Mar 10 19:43:18 2018 Return-Path:X-Original-To: abc3 Delivered-To: [email protected] Date: Sat, 10 Mar 2018 19:43:17 +0800 To: [email protected] Subject: hello wuhuang User-Agent: Heirloom mailx 12.5 7/5/10 Content-Type: text/plain; charset=us-ascii From: [email protected] (root) Status: R wuhuangwansui! & q Held 1 message in /var/spool/mail/abc3 You have mail in /var/spool/mail/abc3
我们还可以自动给邮件给予正文,我们刚才是使用mail命令下的交互式模式中写出正文,只要是从标准输入获取的数据,我们可以使用管道以及重定向来解决自动给予正文的问题。比如我们使用abc3用户给root发送一个文件fatab的内容,标题为‘fstab file’
$ mail -s 'fstab file' root < /etc/fstab
还有一种是通过管道,比如说使用cat命令来查看fstab文件,通过管道送入mail命令。
$ cat /etc/fstab | mail -s 'fatab files' root
我们退回到root用户使用mail命令查看。
# mail Heirloom Mail version 12.5 7/5/10. Type ? for help. "/var/spool/mail/root": 2 messages 2 new >N 1 [email protected] Sat Mar 10 20:14 29/1153 "fstab file" N 2 [email protected] Sat Mar 10 20:18 29/1154 "fstab files" &
那么我们总结一下邮件正文的生成:
邮件正文的生成: (1) 交互式输入;.单独成行可以表示正文结束;Ctrl+d提交亦可。 (2) 通过输入重定向; (3) 通过管道;
那么我们接下来讲述一下周期性任务,以及讲述一下在未来的某一个时刻执行一次某种任务。
二、at命令
at的命令用法其实很简单,就是使用at命令跟上一些选项,之后选择在未来的某个时刻执行,其命令格式如下:
at [OPTION]... TIME
而TIME的使用格式及方法如下:
TIME: HH:MM [YYYY-mm-dd] noon, midnight, teatime tomorrow now+# UNIT: minutes, hours, days, OR weeks
比如说一分钟后运行ls命令,输入完成之后,使用Ctrl+d快捷键退出。而任务是可以写入多个的,在未来的某一时刻中同时运行。
# at now+1min at> ls at>job 1 at Sat Mar 10 20:48:00 2018
我们使用mail命令可以查看运行结果。
# mail >N 3 root Sat Mar 10 20:48 28/607 "Output from your job 1" & 3 Message 3: From [email protected] Sat Mar 10 20:48:01 2018 Return-Path:X-Original-To: root Delivered-To: [email protected] Subject: Output from your job 1 To: [email protected] Date: Sat, 10 Mar 2018 20:48:01 +0800 (CST) From: [email protected] (root) Status: R admin admin.txt anaconda-ks.cfg Desktop Documents Downloads EOF httpd-2.4.25.tar.gz initial-setup-ks.cfg Music Pictures Public scripts Templates Videos &
那么我们需要注意的是,当多个用户执行任务管理繁杂时,以队列的形式用来管理,默认为a队列。
at的作业有队列,用单个字母标识,默认都使用a队列。
at命令的常用选项如下:
常用选项: -l:查看作业队列,相当于atq; -f /PATH/TO/SOMEFILE:从指定文件中读取作业任务,而不用在交互式输入; -d:删除指定作业,相当于atrm; -c:查看指定作业的具体内容; -q QUEUE:指明队列; 注意:作业执行结果是以邮件的形式发送给提交作业的用户;
那么我们在文件中编写任务,交给at命令在两分钟之后执行,这样的话不需要用户进行交互,步骤如下:
# vim at.tasks echo "Hello World" echo "Do you like one you see?" echo "Boy next door!" # at -f at.tasks now+2min
2.1 batch命令
batch和at命令是一样的,但两者不同之处在于batch命令不像at命令一样,指定作业在某个时间运行,而是让系统自行选择,在系统较为空闲的时间去执行指定的任务。也就是说,不用指定时间了,但其它的使用方法与at命令基本相同。
三、周期性任务
周期性任务计划采用的是cron机制,对于cron而言,必须有一种机制到达某种时间执行将其结果进行提交,这种机制就是一种服务,我们需要这种服务一直出于运行状态,而这种服务一直运行在后台,而这种服务需要检查那些任务该执行,所以说这是需要一种服务程序,始终监听并查看对应的时间点去运行的任务是否符合条件,而后将其运行,这种服务程序,在系统上所依靠的程序包为cronle,提供了crond守护进程及相关辅助工具。
周期性任务计划:cron 服务程序: cronle:主程序包,提供了crond守护进程及相关辅助工具; 确保crond守护进程(daemon)出于运行状态: CentOS 7 # systemctl status crond.service Active: active (running)... ... CentOS 6 # service crond status ... is running.
只有以上两种守护进程出于运行状态,我们才能保证其在运行计划中的任务才能可以实现,因此也要像at命令一样,也是需要提交一个或多个任务作业给crond,只不过提交crond作业的方式不同于at,它是需要使用专用的配置文件,该文件有固定的格式,不过不建议使用文本编辑器直接编辑此文件;可使用crontab命令来解决此问题。该命令会自动检查语法错误,一旦发现有什么错误时,会发出提示或直接拒绝提交。
而cron任务共分为两类,一种是系统cron的任务,是为了系统完成自身的维护任务,另一种是用户cron任务,是为了用户的某个需要来实现的。总结如下:
向crond提交作业的方式不同于at,它需要使用专用的配置文件,此文件有固定格式,不建议使用文本编辑器直接编辑此文件;要使用crontab命令。 cron任务分为两类: 系统cron任务:主要用于实现系统自身的维护; 手动编辑:/etc/crontab文件; 用户cron任务: 命令:crontab命令;
对于第一种系统任务来讲,我们不需要手动进行编辑,在系统安装的时候,该任务就会创建完成,我们无需指定,但用户cron是我们需要使用的,并且需要遵守该任务的格式即标准。
我们现在查看一下系统的cron任务的配置文件,该路径在/etc/目录下。
系统cron的配置格式: # cat /etc/crontab SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root # 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
SHELL:指定shell解释器所运行的脚本或命令; PATH:指定某种路径去寻找该命令,不过由于路径太少,可以在写任务时使用绝对路径,或自定义PATH环境变量; MAILTO:运行任务的执行结果通过邮件发送给用户,默认为发送给root;
虽然系统cron配置文件基本不需要更改,或者说很少编辑,但是我们需要了解一下cron文件具体的每一行的解释,记住它的要点。
注意: (1) 每行定义一个cron任务,共7个字段; * * * * * :定义周期性时间; user-name:运行任务的用户身份; command to be executed:任务 (2) 此处的环境变量不同于用户登录后获得的环境,因此,建议命令使用绝对路径,或者自定义PATH环境变量; (3) 执行结果邮件发送给MAILTO指定的用户;
以上就是系统cron的配置,那么接下来我们说一下用户cron的配置。对于用户cron来讲,没有username这一项了,而用户cron的配置文件的路径在:/var/spool/cron/USERNAME。所以在用户cron当中则不需要用户名这一项了。
用户cron的配置格式: SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root # 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 # | | | | | # * * * * * command to be executed
我们需要注意的是,系统cron文件和用户cron文件略有区别,其总结如下:
注意: (1) 每行定义一个cron任务,共6个字段; (2) 此处的环境变量不同于用户登录后获得的环境,因此,建议命令使用绝对路径,或者自定义PATH环境变量; (3) 邮件发送给当前用户;
那么文件格式大体从以上的框架中进行了解,那么接下来我们如何指定时间点。
3.1 时间表示法
对于用户cron和系统cron来说,都是通用的,那么如何指定时间点来说,有以下实现机制:
(1) 特定值: 给定时间点有效取值范围内的值; 注意:day of week和day of month一般不同使用; (2) * 给定时间点有效取值范围内的所有值:表"每..";找时间点最小的* (3) 离散取值:, 在给定的时间点上使用逗号分开多个值即可; #,#,# (4) 连续取值: 在时间点上使用-连接开头和结束; #-# (5) 在制定时间点上,定义步长; /#:#即步长; 注意: (1) 指定的时间不能被步长整除时,其意义将不复存在; (2) 最小时间单位为"分钟",想完成"秒"级任务,得需要额外借助于其它机制; 定义成每分钟任务:而在利用脚本实现在每分钟之内,循环执行多次;
示例:
(1) 3 * * * *:每小时执行一次,每次为三分钟; (2) 4 3 * * 5:每周执行一次;每周5的4点3分; (3) 5 6 7 * *:每月执行一次;每月7号的6点5分; (4) 7 8 9 10 *:每年执行一次,每年10月9号8点7分; (5) 9 8 * * 3,7:每周三和周日; (6) 0 8,20 * * 3,7 (7) 0 9-18 * * 1-5 (8) */5 * * * *:每五分钟执行一次某任务;
3.2 crontab命令
如果某个用户想定义cron任务,我们就可以使用crontab命令就可以了,其命令格式为:
crontab命令: crontab [-u user] [-l | -r |-e][-i]
该命令选项为:
-e:编辑任务; -l:列出所有任务; -r:移除所有任务;即删除/var/spool/cron/USERNAME文件; -i:在使用-r选项移除所有任务时提示用户确认; -u user:root用户可为指定用户管理cron任务;
需要注意的是,不能使用vim编辑器来编写任务计划,因为不能检查其语法错误。
如果你运行的结果没有问题时,可以选择不接收邮件。
注意:运行结果以邮件通知给当前用户;如果拒绝接收邮件: (1) COMMAND > /dev/null (2) COMMAND &> /dev/null
还需要注意一点的是:
注意:定义COMMAND时,如果命令需要用到%,需要对其转义;但放置于单引号中的%不用转义亦可;