Linux 任务计划、周期性任务执行

=============================================================================

概述:

   什么是任务计划呢?就像我们每个人日常生活中都会使用到的闹钟一样,按时的去提醒该去做什么事情,以免忘记。同样,我们在工作当中也要在每天在特定的时间内安排做一些事情,这就是任务计划,本章将学习如何制定Linux系统的任务计划,这里主要包括两种工具:atcrontab

=============================================================================

任务计划简介及电子邮件服务

 1.任务计划介绍

任务计划的分类

  • 一次性的任务计划:只执行一次就结束;

  • 周期性的任务计划:每个一定的时间去做相同的事情;

任务计划使用的命令:

  • 未来时间点执行一次任务:at,batch

  • 周期性运行某任务:crontab

执行结果会通过邮件发送给用户

  • 确定邮件服务器是否开启,执行 netstat -tnlp 或者 ss -tnlp 命令,查看25号端口

 2.邮件服务

本地电子邮件服务:

  • smtp协议:simple mail transmission protocol 简单邮件传输协议;

  • pop3:Post Office Procotol 邮局协议;

  • imap4:Internet Mail Access Procotol 互联网邮件访问协议;

本地主机收发邮件

  • MUA:Mail User Agent,用户收发邮件的工具程序;

mail 命令

语法:mail [-s 'SUBJECT'] username[@hostname]

邮件正文的生成

1)交互式输入:“.”号单独成行可以代表正文结束;Ctrl+d 提交亦可;

  • mail -s 'Hello root' root

2)通过输入重定向:

  • mail -s 'fstab file' root < /etc/fstab

3)通过管道

  • cat /etc/issue |mail -s 'issue file' root

演示:

# 发送邮件,输入标题,指明发送用户
[root@centos7 ~]# mail -s 'hello centos' centos
How are you these days
.
EOT

# 切换到centos用户查收邮件
[root@centos7 ~]# su - centos
[centos@centos7 ~]$ mail
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/spool/mail/centos": 1 message 1 new
>N  1 root                  Fri Feb 24 15:25  18/617   "hello centos"
& 1
Message  1:
From root@centos7.localdomain  Fri Feb 24 15:25:13 2017
Return-Path: <root@centos7.localdomain>
X-Original-To: centos
Delivered-To: centos@centos7.localdomain
Date: Fri, 24 Feb 2017 15:25:13 +0800
To: centos@centos7.localdomain
Subject: hello centos
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=us-ascii
From: root@centos7.localdomain (root)
Status: R

How are you these days

& q

at 命令和 batch命令

at命令未来时间点执行一次任务

at是由atd提供服务的,在使用之前要确认是否开启;

  • CentOS 6:service atd {status|start};

  • CentOS 7:systemctl {status|start} atd

语法:

  • at [option] TIME

TIME:定义出什么时候执行这项任务

  • HH:MM [YYYY-mm-dd];

  • HH:MM[am|pm] [Month] [Date];

  • noon, midnight(午夜), teatime(下午4点),tomorrow

  • now+#{minutes,hours,days, OR weeks}

at 的作业有队列,存放在/var/spool/at 中,用单个字母来表示,默认都使用 a 队列;

选项:

  • -q QUEUE:指明队列;

  • -l:列出指定队列中等待运行的作业;相当于atq;

  • -d #:删除指定作业号的作业;相当于atrm;

  • -c #:查看指定作业号的具体作业任务;

  • -v:可以使用较明显的时间格式列出at中的工作列表;

  • -f /path/from/somefile:从指定的文件中读取任务,不再交互式输入;(# at -f /testdir/at.txt

  • -m:强制at发送邮件,表示执行完毕

注意:

  • 作业执行命令的结果中的标准输出和错误以邮件通知给相关用户

示例:      

1)HH:MM 如:02:00

   在今日的HH:MM 进行,若该时刻已过,则明天此时执行任务

2)HH:MM YYYY-MM-DD 如:04:00 2016-09-20

   规定在某年某月的某一天的特殊时刻进行该项任务

3)HH:MM[am|pm] [Month] [Date]

   04pm March 17

   17:20 tomorrow

4)HH:MM[am|pm] + number [minutes|hours|days|weeks]

   在某个时间点再加几个时间后才进行该项任务

   如:now + 5 minutes

          04pm + 3 days

演示:

# 设定计划任务,在2分钟后执行
[root@centos7 ~]# at now+2min
at> cat /etc/issue
at> ls /var
at> echo "hello there."
at> <EOT>               # 按 Ctrl+d 提交
job 1 at Fri Feb 24 15:49:00 2017

# 查看计划任务
[root@centos7 ~]# at -l 
1	Fri Feb 24 15:49:00 2017 a root

# 从指定文件中读取任务,不在交互式输入
[root@centos7 ~]# at -f at.tasks now+5min
job 2 at Fri Feb 24 16:08:00 2017

[root@centos7 ~]# at -l
2	Fri Feb 24 16:08:00 2017 a root
[root@centos7 ~]# atq
2	Fri Feb 24 16:08:00 2017 a root

# 指明任务编号,删除任务 相当于atrm
[root@centos7 ~]# at -d 2
[root@centos7 ~]# atq

[root@centos7 ~]# at -f at.tasks now+5min
job 3 at Fri Feb 24 16:09:00 2017
[root@centos7 ~]# atq
3	Fri Feb 24 16:09:00 2017 a root
[root@centos7 ~]# atrm 3
[root@centos7 ~]# atq

/etc/at.{allow,deny} 控制用户是否能执行at任务

白名单:

  • /etc/at.allow :默认不存在,只有该文件中的用户才能执行at命令;

黑名单:

  • /etc/at.deny :拒绝该文件中的用户执行at命令,而没有在at.deny 文件中的用户则可以正常执行at命令。

注意:

  • 白名单的优先级是大于黑名单的,如果一旦创建,则只有白名单中的用户才可以执行at命令,其他即使不在白名单中的用户统统没有权限执行at命令;如果没有白名单,则只有黑名单起作用,此时,在黑名单中的用户是不能执行at命令的,不在黑名单中的用户统统默认是允许执行at命令的;

  • 如果两个文件都不存在,只有root 可以执行at 命令

 batch命令

让系统自行选择空闲时间去执行此处指定的任务;

周期性计划任务:cron 

 1.cron介绍

服务程序相关的程序包

  • cronie:主程序包,提供crond守护进程及相关辅助工具;

  • cronie-anacron:cronie的补充程序;用于监控cronie任务执行状况;如cronie中的任务在过去该运行的时间点未能正常运行,则anacron会随后启动一次此任务;

  • crontabs:包含CentOS提供系统维护任务

确保crond守护进程(daemon)处于运行状态

  • CentOS 7:systemctl status crond

  • CentOS 6:service crond status

使用命令

  • 向crond提交作业的方式不同于at,他需要使用专用的配置文件,此文件有固定格式,不建议使用文本编辑器直接编辑此文件,要使用crontab命令可以检查语法是否有错误

cron任务分为两类:

系统cron任务:

  • 主要用于实现系统自身的维护;

  • 手动编辑:/etc/crontab文件

用户cron任务:

  • 命令 crontab

用cron执行的计划任务默认存放在:

  • 日志:/var/log/cron

 2.系统cron配置格式

系统cron的配置格式:/etc/crontab

[root@centos7 ~]# 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

注意:

1)每一行定义一个周期性任务;共7个字段

  • * * * * *:定义周期性时间;

  • user-name:运行任务的用户身份;

  • command to be executed:要执性的任务 

2)此处的环境变量不同用户登录后获得的环境变量,因此,建议命令使用绝对路径,或者自定义的PATH环境变量;

3)执性结果邮件发送给 MAILTO 指定的用户

 3.用户cron配置格式

用户cron配置格式:

  • 配置文件:/var/spool/cron/USERNAME

  • 使用命令:crontab -e

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

注意:

1)每一行定义一个周期性任务;共6个字段

2)此处的环境变量不同股用户登录后获得的环境变量,因此,建议命令使用绝对路径或者自定义的PATH环境变量;

3)邮件发送给当前用户

 4.时间表示法

五个时间点分别是:分钟 小时 天 月 周几

特定值

  • 给定时间点有效取值范围内的值; 

注意:

  • day of week (周几)和 day of month (日)一般不同时使用;

☉ *

  • 给定时间点上有效取值范围内的所有值;表示“每..”(找时间点最小的 *)

示例:

  • 3 * * * *:每小时执行一次,每小时的第三分钟;

  • 3 4 * * 5:每周执行一次,每周五的4点3分;

  • 5 6 7 * *:每月执性一次,每月的7号6点5分;

  • 7 8 9 10 *:每年执行一次,每年的10月9号8点7分;

离散取值:

  • 在时间点上使用逗号分割的多个值:#,#,#

示例:

  • 9 8 * * 3,7:每周三和周日的8点9分;

  • 0 8,20 * * 3,7:每周三和周日的8点和20点

连续取值:-

  • 在时间点导航使用-连接开头和结束:#-#

示例:

  • 0 9-18 * * 1-5:周一到周五(工作时间)内的每小时执行;

在指定时间点上,定义步长:

  • */#:#即步长

注意:

  • 指定的时间点不能被步长整除时,其意义将不复存在;

  • 最小时间单位为“分钟”,想完成“秒”级任务,的需要额外借助其它机制;(即:定义成每分钟任务,而再利用脚本实现每分钟之内,循环执行多次;

示例:

  • */5 * * * *:每5分钟执行一次任务;

  • */7:不能被整除,没有意义

预定义的时间格式

  • @reboot     Run once after reboot.

  • @yearly      ---->  0 0 1 1 * 每年;

  • @annually  ---->  0 0 1 1 * 每年;

  • @monthly  ---->  0 0 1 * *  每月;

  • @weekly    ---->  0 0 * * 0  每周;

  • @daily        ---->  0 0 * * *  每天;

  • @hourly     ---->  0 * * * *  每小时

 4.crontab 命令

crontab命令:

语法:

  • crontab [-u user] [-l | -r | -e] [-i]

选项:

  • -e:打开编辑界面定义任务

  • -l:列出所有任务(仅是当前用户的所有任务);

  • -r:移除所有任务,即删除/var/spool/cron/USERNAME文件;

          如果,删除单个任务应该通过编辑界面删除行实现;

  • -i:在使用-r选项移除所有任务时提示用户确认;

  • -u user:root用户可为指定用户管理cron任务(即为某个用户编辑计划任务);

注意:

运行结果以邮件通知给当前用户;如果拒接接收邮件:

  • COMMAND > /dev/null (执行成功发送给 /dev/null )

  • COMMAND &> /dev/null(不管执行成功和错误都直接发送给 /dev/null,慎用!!!)

定义COMMAND时,如果命令需要用到%,需要对其转义,但放置于单引号中的%不用转义亦可;

  • 如:touch $(date +%Y-%m-%d-%H-%M-%S)

思考:

某任务在指定的时间因关机未能执行,下次开机会不会自动执行?

  • 不会执行! 如果期望某时间因故未能按时执行,下次开机后无论是否到了相应时间点都要执行一次,可使用 ancorn 命令;

如何在秒级别运行任务?

  • * * * * * for min in 0 1 2; do echo "hi"; sleep 20; done

演示:

# 定义周期性计划任务,直接使用 crontab -e 命令,会直接调用 vim 编辑器,并且会检查语法错误
[root@centos7 ~]# crontab -e
crontab: installing new crontab

# 查看定义的计划任务
[root@centos7 ~]# crontab -l
*/5 * * * * /usr/sbin/ntpdate cn.ntp.org.cn > /dev/null

[root@centos7 ~]# crontab -l
*/5 * * * * /usr/sbin/ntpdate cn.ntp.org.cn > /dev/null

# 删除所有任务计划,如果只删除单个
[root@centos7 ~]# crontab -r
[root@centos7 ~]# crontab -l
no crontab for root

 2.为其他用户创建周期性计划任务

# 为 centos 用户创建计划任务,只有 root 有权限
[root@centos7 ~]# crontab -u centos -e
no crontab for centos - using an empty one
crontab: installing new crontab

[root@centos7 ~]# ls /var/spool/cron/
centos  root

[root@centos7 ~]# cat /var/spool/cron/centos 
*/2 * * * * /bin/echo "hello everybody!"

# 查看当前用户的
[root@centos7 ~]# crontab -l
*/5 * * * * /usr/sbin/ntpdate cn.ntp.org.cn > /dev/null

# 查看centos用户的
[root@centos7 ~]# crontab -u centos -l
*/2 * * * * /bin/echo "hello everybody!"

[root@centos7 ~]# crontab -u centos -ri
crontab: really delete centos's crontab? y
[root@centos7 ~]# crontab -u centos -l
no crontab for centos

 5.sleep 命令

sleep

用途

  • sleep命令常用于在Linux shell脚本中延迟时间。

语法:

  • sleep NUMBER [SUFFIX]...

SUFFIX(后缀):

  • s:秒, 默认;

  • m:分;

  • h:小时;

  • d:

示例:

[root@centos7 ~]# date;sleep 5;date
2017年 02月 25日 星期六 11:24:09 CST
2017年 02月 25日 星期六 11:24:14 CST

[root@centos7 ~]# date;sleep 1.5m;date
2017年 02月 25日 星期六 11:25:13 CST
2017年 02月 25日 星期六 11:26:43 CST




案例:

1、每4小时备份一次/etc目录至/backup目录中,保存的文件名称格式为“etc-yyyy-mm-dd-HH”

# mkdir /backup
# crontab -e
 0 */4 * * * /bin/cp -a /etc /backup/etc-`date + '%F-%H'` > /dev/null

2、每周2, 4, 7备份/var/log/messages文件至/logs目录中,文件名形如“messages-yyyymmdd”

# mkdir /logs
# crontab -e
# 20 1 * * 2,4,0 /bin/cp -a /var/log/messages /logs/messages-`date +'%Y%m%d'` > /dev/null

3、每两小时取出当前系统/proc/meminfo文件中以S或M开头的信息追加至/tmp/meminfo.txt文件中

# crontab -e
# 20 */2 * * * /bin/grep -e '^S' -e '^M' /proc/meminfo >> /tmp/meminfo.txt

4、工作日时间内,每两小时执行一次“ip addr show”命令

# crontab -e
# 0 9-17/2 * * 1-5 /sbin/ip addr show