本文旨在复习Linux内部的Mail机制以及任务计划基本原理和用法。
知识储备
- 任务计划通常分为2类:
- 未来一次性执行的计划[at、batch]
- 未来周期性执行的计划[crontab]
- 无论是at、batch、crontab,任务计划在执行后都会通过邮件的方式发送给管理员和用户,请注意无论执行成功或者失败都会发送邮件哦;
- 邮件是Mail命令来支撑的,当然Mail还可以支撑其他任何需要调用邮件的程序或服务,很多维护类的工作会以邮件的方式发送给管理员;
- 每个用户被创建后系统会给用户一个邮筒,默认是/var/spool/mail/UserName这个文件;
Mail基本原理[CentOS7上是Mailx]
● 电子邮件服务通常用到这么几种协议
SMTP,25端口,是服务器到服务器的真正意义的邮件投递协议
POP3:110端口,是用户从邮件服务器上取得邮件遵循的协议
IMAP4:143端口,同上,还有其他的客户端邮件协议
● 邮件发送与接收流程是这样的
● 默认情况下,Mail命令是不支持向外收发邮件,25端口监听的是本机回环地址,见下图
● 默认Linux会给每个创建的新用户分配一个邮筒[可收发邮件],在/var/spool/mail/下,见下图
Mail基本用法
● 发送邮件
mail -s ‘Subject‘ [email protected] 此时需要手动输入正文,CTRL+D结束
mail -s ‘Subject‘ [email protected] </PATH 将文件内容作为正文发送
COMMAND | mail -s ‘Subject‘ [email protected] 将命令结果以管道送入mail做正文
● 例:使用lance用户给root发送一封测试邮件
● 接收邮件
登录后mail即可进入mail命令的交互式接口
在&后输入指定的邮件编号即可查看该邮件了
● 例:接收刚才收到的邮件
At命令
● 指定未来某个时间点做某个作业,通常都是一次性执行,时间点必须指定
● 指定时间点后,会进入交互式接口,此时可以定义要执行的命令,CTRL+D退出
● 作业是有队列的概念的,有队列标识符,默认为队列a,可以通过-q指定队列编号
Usage
At [OPTIONS]... TIME
常用OPTIONS
-q [a,b,c,d...] 作业是有不同队列的,默认处于队列a,队列编号从a,b,c,d...开始请注意:使用#at -q b now+3hour 能够将这个3小时后执行的作业放在队列b中!-l 查看队列中待运行作业列表;相当于atq命令,可以和-q配合使用-f /path 从指定的文件中读取要运行的作业,你得先编辑好作业文件-d # 删除指定编号的作业 相当于atrm-c AT_JOB_NUM 查看待运行作业的内容; 请注意:队列的编号是从a,b,c,d...的, 而作业序列是始终递增的, 每新来一个作业就+1, 即便前一个作业没有成功执行仍然会+1 你懂的。会显示运行环境的~~ 最后才会显示运行命令代码读取到的环境变量和当前用户在命令行中读取的环境变量未必一致 懂吗?所以未必是用户登陆后能执行的命令就一定可以提交给at来执行建议:提交的作业中的命令如果不是在下列4个路径中/bin /sbin /usr/sbin /usr/bin 建议使用绝对路径
关于TIME
● 请注意时间点必须指定,必选的,TIME时间形式通常有3种调用
绝对时间:预先定义的一些时间点,如noon[12点]、teatime[16点]、midnight[24点]、Tomorrow
相对时间:Now+3hour,单位可以是minute,hour,day,week请注意不要末尾加s
模糊时间:13:14,形如HH:MM,MMDD[CC]YY MM/DD/[CC]YY DD.MM.[CC]YY这些等等
● 例:创建一个a队列作业,一个b队列作业查看作业列表,并删除a作业
● 例:查看4作业的内容,观察是否显示运行环境
Batch
和at基本一模一样,只不过系统自行选择在资源较为空闲的时候运行作业,不需要指定时间!
Crontab任务基本原理
● 周期性的任务计划,通常表现为每几天做一次,每几周做一次等
● 怎样做到周期性执行呢?是由守护进程在等待,一旦发现条件满足就执行
● 周期性任务计划有2类
系统Cron任务
/etc/crontab,不建议使用系统cron,可以使用vim编辑,没有默认运行用户身份,需要指定运行
用户Cron任务
/var/spool/cron/Username,建议使用用户Cron任务,以提交者身份运行,可以vim,建议使用Crontab命令来
Crontab命令基本用法
谈Crontab任务的基本用法,说白了就是摸清楚怎么定义周期性时间,5个位置*分别含义已在上图给出
● *代表的意思是每这个时间间隔就执行一次的意思
(1) * * 1 1 * date表示每年1月1日执行一次date命令
(2) 5 8 * * * ls 表示每月每天8点5分执行一次ls命令
● 不建议第3,4位 和 第5位 一起使用
(1) * * 8 8 6 ls表示8月8日并且这天恰巧是周六才会执行ls命令
● 连续时间范围表示
(1) 3-7 * * * * ls表示每月每天每小时的3-7分钟,每分钟执行一次ls,请注意
● 离散时间点表示
(1) 3,7 * * * * ls表示3分钟执行一次ls,7分钟执行一次ls,其他同上
● 频率表示*/#
(1) * */3 * * * ls表示每3小时执行一次ls
(2) */20 * * * *ls 表示每20分钟执行一次ls
常用OPTIONS [ Crontab [-u user] [ -l | -r | -e ] ]
-l 列出任务
-r 移除所有任务,如果想移除某一个任务,可以编辑文件删除或者注释该行
-e 编辑,采用当前shell进程的默认编辑器来编辑
-u user 管理指定user的Crontab任务计划周期表,只有管理员可以,普通用户禁止访问别人的crontab表,原因见下文“注意”
Crontab的注意事项
● 一切任务计划都是由守护进程crond在后台运行的,这个守护进程属主是root,根据进程的安全上下文,该进程就可以读用户的crontab了,能读到。但是出于一些安全考虑,用户自己的crontab不希望被别人读取,那么就不需要读取权限,这是为了安全。
● Crontab定义频率执行的问题
*/20 * * * *定义为每20分钟执行一次,1小时3次,没问题;
*/40 * * * *定义为每40分钟执行一次,40分钟不能被60分钟整除,即频率点不能被时间范围整除,会出问题;
● 那么如何定义每8分钟执行一次呢?
* * * * * sleep 8m;echo ‘Hello!‘使用sleep延迟来实现每8分钟自动执行
Sleep #默认单位是秒,还可以用m分钟,h小时,d天等
Crontab精确到每秒执行
● 本质上Crontab只能实现分钟级的周期性任务,精确到秒可以使用sleep实现
* * * * * sleep 20;echo ‘Yuyu!‘
● 机器恰巧在执行点不在线,Crontab如何处理呢?
如果定义为每天3点执行,而夜晚23点关机,早上7点开机,那么Crontab将失效;
anacron可以作为补充,开机自动检查上次计划是否成功执行,否则强制执行一次
● 实例:周期类维护任务如果频率太高,那么造成邮件通知太频繁,如何禁止呢?
COMMAND > /dev/nul 正确执行则不发送邮件,有错误还是会发送邮件
COMMAND &> /dev/nul 无论正确错误都丢到垃圾桶
● Crontab中规定的任务的命令执行环境 和用户自身的环境未必是一样
所以在定义任务时建议路径使用绝对路径,如果是Scripts,那么最好也用绝对路径,或者在Scripts开头导入环境变量。
● 对于Crontab,%有特殊功用,如果命令中出现,需要转义,或者单引号对其引用