我自己博客网站里的文章
 
Linux周期任务:at和crontab
每个人或多或少都有一些约会或者是工作,有的工作是长期周期性的, 例如:
- 每个月一次的工作报告
- 每周一次的午餐会报
- 每天需要的打卡
- ……
有的工作则是一次性临时的,例如:
- 刚好课题组老师演讲,需要你明天准备演讲器材等等
- 临时和师妹晚上约了吃饭
- ……
同理,Linux中也有很多周期性任务或者临时任务,例如:
- 每周打包一份备份文件:每周一的凌晨 3:25 把/home/wwwroot 目录打包备份为 backup.tar.gz。
- 今晚 23:30 重启网站服务
- ……
为此,Linux中提供了at和crontab两个程序来完成一次性临时任务和长期周期任务。
1. 一次性临时任务:at
at命令 用于在指定时间执行命令。
A. 启动atd
为了能够在指定的时间执行命令,需要有一个守护进程在后台不断地运行,而后到指定的时间之后运行我们指定的程序。这个守护进程就是 atd。因此,为了使用at程序,需要先开启 atd 守护进程。Linux中使用 systemctl 来管理所有的守护进程,包括启动、重启、禁止、……
首先开启 atd 守护进程启动那个服务
sudo systemctl enable rpc-statd
然后启动一下 atd 守护进程(默认是启动的,这里是以防万一)
sudo systemctl start atd
最后查看一下 atd 守护进程的状态
systemctl status atd

可以看到正常在运行
B. at配置文件
atd 通过两个文件 /etc/at.allow 和 /etc/at.deny 来决定系统中哪些用户可以使用 at 设置定时任务
- 它首先检查 /etc/at.allow,如果文件存在,则只有文件中列出的用户(每行一个用户名)能使用at
- 如果 /etc/at.allow不存在,则检查文件/etc/at.deny,不在此文件中的所有用户都可以使用at
- 如果 /etc/at.deny是空文件,则表示系统中所有用户都可以使用at
- 如果 /etc/at.deny文件也不存在,则只有root才能使用at
C. 时间指定格式
at允许使用一套相当复杂的指定时间的方法。
- 它能够接受在当天的hh:mm(小时:分钟)式的时间指定。假如该时间已过去,那么就放在第二天执行。
- 当然也能够使用midnight(深夜)、noon(中午)、teatime(饮茶时间,一般是下午4点)等比较模糊的词语来指定时间。
- 用户还能够采用12小时计时制,即在时间后面加上AM(上午)或PM(下午)来说明是上午还是下午。
- 也能够指定命令执行的具体日期,指定格式为month day(月 日)或mm/dd/yy(月/日/年)或dd.mm.yy(日.月.年)。指定的日期必须跟在指定时间的后面。
不过一般不会使用这种绝对时间写法,而是使用相对时间写法。这对于安排不久就要执行的命令是很有好处的。
指定格式为:
now + count time-units
- now就是当前时间
- time-units是时间单位,这里能够是- minutes(分钟)、- hours(小时)、- days(天)、- weeks(星期)。
- count是时间的数量,究竟是几天,还是几小时
还有有一种计时方法就是直接使用today(今天)、tomorrow(明天)来指定完成命令的时间。
D. 语法
at的语法如下:
at <时间> [选项]
其中,
- <时间>是指定任务执行时间的参数,可以是具体的时间或者相对时间。
- 选项用于指定一些额外的设置,例如任务的优先级、环境变量等。
一般来说,在输入完时间和选项后,按下回车就进入到at的交互终端了。在这个终端中我们可以输入我们需要执行的命令。完成输入后按下Ctrl+D结束输入
Ctrl+D是Shell输入结束符的方式
at now+1min
warning: commands will be executed using /bin/sh
at> echo "1 min passed"
at> <EOT>
job 2 at Sun Jul 16 12:51:00 2023

另外一种方式就是使用-f参数,然后指定需要运行的脚本文件就行了
C. 运行结果
at命令默认情况下不会将任务的输出直接发送到命令行。因此,需要我们在at中写的任务的把输出重定向到一个文件中,该文件可以在任务执行完成后进行查看。
不过一般我们更喜欢能够at能够类似于闹钟一样,任务执行完可以以某种方式提醒我们,所以一般直接在任务的最后结合一个mail命令来向我们的邮箱发邮件
注意,通过Linux系统自带的mail命令默认只能给本机的其他用户发邮件,如果需要对公网邮箱发送邮件,需要配置一下。具体来说,mail命令是依赖sendmail的,所以我们需要先检查安装和配置sendmail。一般系统都自带sendmail,但是只能给内网的邮箱发邮件。如果想给公网的邮箱发邮件(比如qq邮箱)就需要配置sendmail。
配置也比较简单,因为发邮件是应用层,所以配置一下SMTP协议的相关信息就行了。
D. 选项
-f:指定包含具体指令的任务文件;
-q:指定新任务的队列名称;
-l:显示待执行任务的列表;
-d:删除指定的待执行任务;
-m:任务执行完成后向用户发送E-mail。一般多在任务中用mail命令
E. 参数
日期时间:指定任务执行的日期时间。
F. 实例
明天17点钟,输出时间到指定文件内:
[root@localhost ~]# at 17:20 tomorrow
at> date >/root/2013.log
at> <EOT>
job 8 at 2013-01-06 17:20
计划任务设定后,在没有执行之前我们可以用atq命令来查看系统没有执行工作任务:
[root@localhost ~]# atq
8       2013-01-06 17:20 a root
7       2013-01-08 17:00 a root
删除已经设置的任务:
[root@localhost ~]# atq
8       2013-01-06 17:20 a root
7       2013-01-08 17:00 a root[root@localhost ~]# atrm 7
[root@localhost ~]# atq
8       2013-01-06 17:20 a root
显示已经设置的任务内容:
[root@localhost ~]# at -c 8
#!/bin/sh
# atrun uid=0 gid=0
# mail     root 0
umask 22此处省略n个字符
date >/root/2013.log
2. 长期周期性任务:crontab
crontab命令 被用来提交和管理用户的需要周期性执行的任务,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动crond进程,crond进程每分钟会定期检查是否有要执行的任务,如果有要执行的任务,则自动执行该任务。
A. 语法
crontab(选项)(参数)