我自己博客网站里的文章
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(选项)(参数)