Linux 任务计划
1.实验介绍
1.1 实验内容
我们经常会需要安排脚本在某个时间或每隔一段时间来运行,如周期性的清理一下 /tmp,周期性的去备份一次数据库,周期性的分析日志等等。而且有时候因为某些因素的限制,执行该任务的时间会很尴尬。Linux 调度通过 crontab 与 at 这两个工具。
1.2 实验知识点
- at 使用
- crontab 语法
1.3 crontab 与 at
- at:处理仅执行一次就结束调度的指令。这次做完以后就没有。
- crontab:周期性需要执行的任务。
2. at的使用
2.1 at简介
设置 at 命令很简单,只是运行的时间,就会在那个时候运行。类似于打印进程,会把任务放到 /var/spool/at 目录中,到指定时间运行它。
/etc/at.allow 和 /etc/at.deny 管理使用限制,写在 /etc/at.allow 中的用户才能使用 at,写在 /etc/at.deny 中的用户不能使用 at。若这两个文件不存在,则只有 root 用户可以使用 at。
2.2 at 准备
使用单一工作调度,首先应启动 atd 服务。实验环境默认没有此服务,需要安装并启动
# 安装
sudo apt-get install at
# 启动atd
sudo service atd start
service 是 Linux 中非常常用的命令,用户启动已安装的服务,其主要是读取 /etc/init.d 中的脚本,并执行相关的脚本,通过参数来控制相关服务的状态,如启动、关闭、重启等等。
关于一些 service 常用的操作有:
- start //启动服务
- stop //关闭服务
- restart //重启服务
- reload //重新载入配置
- status //查看服务状态
2.3 at 使用
可以通过 man at 查看 at 的帮助文档(关于帮助相关的命令在后续的章节会统一讲解)
2.3.1 基本语法
at (选项) (参数)
选项:
选项 | 意思 |
---|---|
-f | 指定包含具体命令的任务文件 |
-q | 指定新任务的队列名称 |
-l | 显示待执行任务的列表 |
-d | 删除指定的待执行任务 |
-m | 任务执行完成后向用户发送email |
参数:
参数为日期时间,格式如下:
绝对计时
(1)midnight(深夜),noon(中午),teatime(饮茶时间,一般是下午4点)
(2)hh:mm today,hh:mm tomorrw。例如:14:30 today 今天下午两点半,14:30 tomorrow 明天下午两点半
(3)12小时制,时间后面加am(上午),pm(下午)。例如:2:30 am 上午两点半,2:30 pm 下午两点半
(4)日期的表示的方式有:月日或者 mm/dd/yy(月/日/年)或者 dd.mm.yy(日.月.年)或者 yy-dd-mm(年-月-日)。例如 14:30 17.10.25 或者 14:30 25.10.17 或者 14:30 2017/10/25(2017 年 10 月 25 日下午两点半)
相对计时
at now + 时间数量 时间单位。时间单位可以是 minutes(分钟),hours(小时),days(天),weeks(星期)。例如 at now + 3 minutes(3 分钟后)
2.3.2 at 的应用
下面我们开始进入到实践环节:
(1)两分钟后写 hello shiyanlou 到 my.txt 中
首先
$ at now + 2 minutes
然后按 enter 键,输入以下
at> echo "hello shiyanlou" > my.txt
at> <EOT> //这里按ctrl + D 自动出现<EOT>
job 1 at Wed Oct 25 18:01:00 2017
上面的最后一句意为第一个 at 工作将在 2017 年 10 月 25 日星期三的 18:01:00 运行可以使用 atq 或者 at -l 查看
$ atq
1 Wed Oct 25 18:18:00 2017 a shiyanlou
atq 如果没查到,那是因为过了两分钟了,该任务已经执行了。
(2)在今天 18:28 输出时间到 time.log 中
$ at 18:28 today
at> date > time.log
at> <EOT>
job 2 at Web Oct 25 18:28:00 2017
# 可以使用如下命令将第2项工作内容列出来
$ at -c 2
查看 time.log 中的内容
(3)在固定时间添加一个用户
$ at 06:39pm
at> sudo useradd aaa
at> <EOT>
job 3 at Web Oct 25 18:36:00 2017
可以看到最后有个aaa的用户
(4)在2017年10月26日 18:00 关机
$ at 18:00 2017-10-26
at> sudo /bin/sync
at> sudo /bin/sync
at> sudo /sbin/shutdown -h now
at> <EOT>
job 5 at Thu Oct 26 18:00:00 2017
要是发现写错了,想删除怎么办,可以使用 atrm 命令,该命令的作用是删除待执行的任务队列中的指定任务。
其命令的格式是:atrm 任务号
2.3.3 batch
batch 的命令是在指定时间当 cpu 工作负载小于 0.8 的时候才执行。例如在 2017 年 10 月 26 日 18:00 关机,如果当时负载太高,则暂缓执行。
$ batch 18:00 2017-10-26
at> sudo /bin/sync
at> sudo /bin/sync
at> sudo /sbin/shutdown -h now
at> <EOT>
job 5 at Thu Oct 26 18:00:00 2017
2. crontab 的使用
2.1 crontab 简介
crontab 命令常用于 Unix 和类 Unix 的操作系统之中(Linux 就属于类 Unix 操作系统),用于设置周期性被执行的指令。它通过守护进程 cron 使得任务能够按照固定的时间间隔在后台自动运行。cron 利用的是一个被称为 "cron 表"(cron table)的文件,这个文件中存储了需要执行的脚本或命令的调度列表以及执行时间。
这个工具非常有用,例如我们需要在半夜执行数据库的 patch 脚本,例如我们需要半夜升级我们的站点,有了 crontable 我们就不需要半夜起来执行脚本,亦或者是因为睡过头而错过该执行的任务。
和 at 相似,使用限制的配置文件在 /etc/cron.allow 和 /etc/cron.deny 中。当使用者使用 crontab 后,该项工作会被记录到 /var/spool/cron/ 里。不同用户执行的任务记录在不同用户的文件中。
通过 crontab 命令,我们可以在固定的间隔时间或指定时间执行指定的系统指令或脚本。时间间隔的单位可以是分钟、小时、日、月、周的任意组合。
这里我们看一看 crontab 的格式
# 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
其中特殊字符的意义:
特殊字符 | 意义 |
---|---|
* | 任何时刻 |
, | 分割时间,例如0 7, 9 * command 代表7:00和9:00 |
- | 时间范围,例如30 7-9 * command 代表7点到9点之间每小时的30分 |
/n | 每隔n单位间隔,例如/10 * 每10分钟 |
2.2 crontab 准备
crontab 在本实验环境中需要做一些特殊的准备,首先我们会启动 rsyslog,以便我们可以通过日志中的信息来了解我们的任务是否真正的呗执行了(在本实验环境中需要手动启动,而在自己本地中 Ubuntu 会默认自行启动不需要手动启动)
sudo service rsyslog start
在本实验环境中 crontab 也是不被默认启动的,同时不能在后台由 upstart 来管理,所以需要我们手动启动它(同样在本实验环境中需要手动启动,自己的本地 Ubuntu 的环境中也不需要手动启动)
sudo cron -f &
2.3 crontab 使用
2.3.1 基本语法
crontab [-u username] [-l|-e|-r]
其常用的参数有:
选项 | 意思 |
---|---|
-u | 只有root才能进行这个任务,帮其他使用者创建/移除crontab工作调度 |
-e | 编辑crontab工作内容 |
-l | 列出crontab工作内容 |
-r | 移除所有的crontab工作内容 |
2.3.2 crontab 的应用
添加一个计划任务
crontab -e
第一次启动会出现这样一个画面,这是让我们选择编辑的工具,选择第一个基本的 vim 就可以了
选择后我们会进入这样一个画面,这就是添加计划的地方了,与一般的配置文档相同,以#号开头的都是注释
因为使用的是 vim,按 i 键便可编辑文档,在文档的最后一行加上这样一行命令,该命令的意思是每分钟我们会在 /home/shiyanlou 目录下创建一个以当前的年月日时分秒为名字的空白文件
*/1 * * * * touch /home/shiyanlou/$(date +\%Y\%m\%d\%H\%M\%S)
输入完成后按 esc 再输入 :wq 保存并退出。
注意
"%" 在 crontab 文件中,有结束命令行、换行、重定向的作用,前面加"\"符号转义,否则,"%" 符号将执行其结束命令行或者换行的作用,并且其后的内容会被做为标准输入发哦少年宫给前面的命令。
添加成功后我们会得到 installing new crontab 的一个提示。
为了确保我们任务添加的正确与否,我们会查看添加的任务详情:
crontab -l
虽然我们添加了任务,但是如果 cron 的守护进程并没有启动,当然也就不会帮我们执行,我们可以通过以下 2 种方式来确定我们的 cron 是否成功的在后台启动,若是没有则需要启动一次。
ps aux | grep cron
# 或者使用下面
pgrep cron
ps 的相关命令会在后续详细讲解,这里主要是为了查看 crontab 的后台程序是否正确执行。
查看任务执行创建出来的文件,验证我们的计划任务有正确执行:
同样我们通过这样一个命令可以查看到执行任务命令之后在日志中的信息反馈:
sudo tail -f /var/log/syslog
从中我们同样可以验证所添加的任务又被执行,可以按 ctrl + c 可以退出当前的状态。
当我们并不需要某个任务的时候我们可以通过 -e 参数去配置文件中删除相关命令,若是我们需要清除所有的计划任务,我们可以使用这么一个命令去删除任务:
crontab -r
下面将通过一下例子来巩固大家对 crontab 的学习:
(1)每天中每小时的第5分钟执行脚本 test.sh
首先在 /home/shiyanlou 下创建 test.sh 脚本
vim test.sh
并在其中输入以下内容:
#! /bin/bash
touch /home/shiyanlou/$RANDOM
按 esc 然后输入 :wq 保存退出,完成脚本的编辑。
紧接着添加一个计划任务:
crontab -e
输入以下内容:
05 * * * * /home/shiyanlou/test.sh
(2)每天的凌晨的3、4、5点执行 test.sh
00 3, 4, 5 * * * /home/shiyanlou/test.sh
(3)周日每隔3小时执行 test.sh
00 */3 * * 0 /home/shiyanlou/test.sh
(4)每天的下午7点关闭计算机
00 19 * * * /sbin/shutdown -h
3. crontab 的深入
每个用户使用 crontab -e 添加计划任务,都会在 /var/spool/cron/crontabs 中添加一个该用户自己的任务文档,这样目的是这个隔离。
如果是系统级别的定时任务,应该如何处理?只需要以 sudo 权限编辑 /etc/crontab 文件就可以。
cron 服务监测时间最小单位是分钟,所以 cron 会每分钟去读取一次 /etc/crontab 与 /var/spool/cron/crontabs 里面的内容。
在 /etc 目录下,cron 相关的目录有下面几个:
每个目录的作用:
- /etc/cron.daily,目录下的脚本会每天执行一次,在每天的6点25分时运行;
- /etc/cron.hourly,目录下的脚本会每小时执行一次,在每小时的17分钟时运行;
- /etc/cron.monthly,目录下的脚本会每月执行一次,在每月1号的6点52分时运行;
- /etc/cron.weekly,目录下的脚本回每周执行一次,在每周第七天的6点47分时运行;
系统默认执行时间可以根据需求进行修改。
参考链接
本章部分描述参考下面的文档实现,想进一步的学习该知识或者相关知识推荐查看: