在 Linux 中的任务计划的实现有两种:
- 未来的某时间点执行一次任务,可使用
at
、batch
命令实现; - 周期性运行某任务,可使用
cron
命令实现;
指定时间点执行计划-at
at
命令可以指定一个时间点来运行某任务。
常用格式如下:
at [option] [time]
option:常用选项
-l:列出等待执行的作业队列中的队列信息,相当于 atq;
-d #:删除作业号为 # 的作业,作业号可通过 -l 查看,相当于 atrm #;
-c:查看具体的作业信息;
-f:从指定的文件中读取任务内容;
time:指定方式有如下几种:
1、指定任务执行的时间点,格式为:HH:MM [YYYY-mm-dd];
2、还可模糊指定,如:
noon 表示正午 12 点;
midnight 表示夜里 12 点;
teatime 表示下午 4 点;
tomorrow 表示明天;
3、now+#{minutes|hours|days|weeks} 指定多久之后执行,如 at now+3minutes 表示 3 分钟之后执行;
作业的执行结果会以邮件的方式发送给相关用户。
例:我要设置一个任务在 21:44
分执行,任务要执行的命令如下:
echo hello zze
那么我可以执行如下命令:
[root@zzehost ~]# at 21:44
at> echo hello zze
at> <EOT>
job 2 at Tue Dec 10 21:44:00 2019
在进入到 at
的提示符下输入完要执行的命令后,可通过 CTRL + D
结束输入,任务则创建成功。
当时间到 21:44 时,所指定任务的执行结果会通过邮件的方式发送给用户。
查看邮件:
空闲时执行计划-batch
batch
命令的作用是让系统自行选择空闲时间去执行此处指定的任务,不可指定时间点。
直接看示例:
[~]: echo "echo hello from batch" | batch
job 3 at Wed Dec 11 15:49:00 2019
该种方式很少使用,简单了解即可。
周期性任务计划-cron
周期性任务计划指的是一个作业需要反反复复执行 n 遍的,只要时间点满足设定的情况计划就会运行。
对 Linux 来讲,周期性任务计划是通过 cron 来实现的,相关的程序包可通过 rpm -qa | grep cron
查看:
[~]: rpm -qa | grep cron
cronie-1.4.11-19.el7.x86_64
cronie-anacron-1.4.11-19.el7.x86_64
crontabs-1.11-6.20121102git.el7.noarch
cronie
:主程序包,提供了 crond 守护进程及相关辅助工具;cronie-anacron
:cronie
的补充程序,用于监控cronie
任务的执行状况,如果cronie
中的任务在过去该运行的时间点未能运行,则anacron
会随后启动一次此任务;crontabs
:包含 CentOS 提供的系统维护任务;
crond 守护进程必须正常运行,其它定义的任务才能在指定时间点正常运行。
- CentOS 6 可通过
service crond status
查看 crond 守护进程的状态;- CentOS 7 可通过
systemctl status crond
查看 crond 守护进程的状态;
计划要周期性执行的任务提交给 crond,由其来实现到点运行。
Linux 系统中有两类周期性任务:
- 系统 cron 任务(系统维护作业):通过编辑
/etc/crontab
配置文件实现; - 用户 cron 任务:使用
crontab
命令将任务提交给 crond 守护进程;
系统cron任务
系统 cron 任务最终所编写的作业需要保存在 /etc/crontab
文件中,这个文件需要遵循特定格式,查看该文件:
在该文件注释中已经做了明了的说明,定义一个任务需要 7 列,每列所表示的含义如下(序号与列顺序对应):
- 分钟;
- 小时;
- 日;
- 月;
- 周几;
- 以
user-name
的身份执行; - 要执行的命令;
即通过这 7 列能指定一个命令在几月几日(或周几)的几点几分以谁的身份执行指定命令。
编写要执行的命令时最好使用绝对路径,在
/etc/crontab
的第 3 行可以看到该文件导入的环境变量其实是很少的,如果使用相对路径且使用的命令不在path
指定的路径下,就会出现到执行时间点执行时找不到命令的情况。
这些时间的指定还有特殊的时间表示法:
- 特定值:仅指定时间点执行;
*
:所有时间点执行;- 离散取值:使用
,
分割,如在小时位使用2,4,6
则表示在 2 点、4 点、6 点时执行; - 连续取值:使用
-
分割,如在小时位使用2-6
则表示在 2 点到 6 点执行; - 在指定时间单位上定义步长:格式为
*/#
,*
为时间范围,#
就是步长,如在分钟位使用*/2
则表示每 2 分钟执行,也可在指定时间范围内定义步长,如在分钟位使用20-50/3
则表示在 20 到 50 分时每 3 分钟执行,要注意的是,该方式的步长要能被指定的时间点所整除才会准时执行;
示例
例 1 :每天晚上 9 点 10 分以 root 用户的身份运行 echo hello
。
10 21 * * * root /usr/bin/echo hello
例 2 :每 3 小时在整点以 root 用户的身份运行 echo hello
。
0 */3 * * * root /usr/bin/echo hello
用户cron任务
用户 cron 任务是用户通过 crontab
命令定义的,每个用户都有专用的 cron 任务文件 /var/spool/cron/<username>
,而 crontab
命令实际上就是编辑该文件,并且带有语法检查功能。
使用格式如下:
crontab [-u user] [-l | -r | -e] [-i]
-e:打开任务编辑窗口;
-l:查看任务列表;
-r:移除所有任务,如果要删除某一个任务直接通过 -e 在编辑窗口删除一行即可;
-i:同 -r 一起使用,以交互式模式有选择地移除指定任务;
-u user:仅 root 可用,为指定用户创建 cron 任务;
因用户 cron 任务也是定义在文件中,所以实际上也可以通过编辑文件来定义任务,但是不建议这样做,因为
crontab
命令创建任务时带有语法检查的功能,而直接编辑任务文件出错也不自知。
用户通过 crontab
命令创建任务时这个任务默认就使用该用户的身份运行任务,不需要指定以哪个用户的身份运行,任务文件的规则及列顺序与系统 cron 任务的文件定义相同,去除第 6 列用户身份即可。
示例
例 1 :每天晚上 9 点 10 分运行 echo hello
。
执行 crontab -e
打开编辑窗口(操作与 VIM 一致),输入以下内容保存即可:
10 21 * * * /usr/bin/echo hello
注意
- 不管是系统 cron 任务还是用户 cron 任务的执行结果默认都是以邮件方式发送给相关用户,如果不希望发送邮件,则可使用
COMMAND > /dev/null
或COMMAND &> /dev/null
将输出信息重定向; - 对于 cron 任务来讲,
%
有特殊用途,如果要在命令中使用%
,则需要转义(\%
),也可以将%
放置在单引号中则不需要转移;
练习
1、每 4 小时备份一次 /etc
目录至 /backup
目录中,保存的文件名称格式为 etc-yyyy-mm-dd-HH.tar.xz
。
[~]: cat scripts/cron-tar.sh
#!/bin/bash
#
#
t=`date +%Y-%m-%d-%H`
mkdir /backup/etc-$t
cp /etc/* /backup/etc-$t
tar -c -f /backup/etc-"$t".tar /backup/etc-$t
xz /backup/etc-"$t".tar
rm -df /backup/ect-$t
[~]: crontab -l
20 */4 * * * /usr/bin/bash /root/scripts/cron-tar.sh
2、每周 2,4,7 备份/ var/log/messages
文件至 /logs
目录中,文件名形如 messages-yyyymmdd
。
* * * * 2,4,7 /usr/bin/cp /var/log/messages /logs/messages-`date +%Y%m%d`
3、每两小时取出当前系统 /proc/meminfo
文件中以 S
或 M
开头的信息追加至 /tmp/meminfo.txt
文件中。
[~]: touch /tmp/meminfo.txt
[~]: crontab -l
20 */2 * * * /usr/bin/grep "^[SM]" /proc/meminfo >> /tmp/meminfo.txt
4、工作日时间内,每小执行一次 ip addr show
命令。
0 * * * 1-5 /usr/sbin/ip addr show
评论区