Linux周期任务

我自己博客网站里的文章
Linux之crontab命令

Linux周期任务:at和crontab

每个人或多或少都有一些约会或者是工作,有的工作是长期周期性的, 例如:

  • 每个月一次的工作报告
  • 每周一次的午餐会报
  • 每天需要的打卡
  • ……

有的工作则是一次性临时的,例如:

  • 刚好课题组老师演讲,需要你明天准备演讲器材等等
  • 临时和师妹晚上约了吃饭
  • ……

同理,Linux中也有很多周期性任务或者临时任务,例如:

  • 每周打包一份备份文件:每周一的凌晨 3:25 把/home/wwwroot 目录打包备份为 backup.tar.gz。
  • 今晚 23:30 重启网站服务
  • ……

为此,Linux中提供了atcrontab两个程序来完成一次性临时任务和长期周期任务。

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

查看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+DShell输入结束符的方式

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

at输入命令

另外一种方式就是使用-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(选项)(参数)