Linux计划任务

有时需要在某个指定的时间执行一个操作,此时就要使用计划任务了。计划任务有两种:一个是at计划任务,另一个是 crontab计划任务。

下面我们分别来看这两种计划任务的使用方法。

1.at

at计划任务是一次性的,到了指定的时间点就开始执行指定的命令,执行完成之后,不会重复执行这个命令

首先查看系统中是否存在at计划任务,命令是atq或at -1(字母1)

复制代码
[root@jiayi ~]# atq
[root@jiayi ~]# 
[root@jiayi ~]# at -l

这两个命令都没有任何输出,说明当前系统中并不存在任何计划任务。下面开始创建at计划任务,at的用法如下

复制代码
at 时间点 <按【Enter】键>
> 输入要执行的命令
Ctrl+D 提交

例如,要在2023年12月08日执行hostname命令

复制代码
[root@jiayi ~]# at 2023-12-08
warning: commands will be executed using /bin/sh
at> hostname   
at> <EOT>
job 3 at Fri Dec  8 14:11:00 2023

这里只是指定了日期,并没有指定在2025年12月12日的几点执行。那么,创建这个计划任务时是几点几分,例如,这里是在19点11分创建的at计划任务,那么到了2023年12月08日的19点11分就要自动执行hostname命令了

如果要指定某个时间点,格式如下

复制代码
at 时间 日期 <按【Enter】键>
> 输入要执行的命令
Ctrl+D 提交

例如,要在2023年12月08日上午10点执行 hostname命令

复制代码
[root@jiayi ~]# at 10:00 2023-12-08
warning: commands will be executed using /bin/sh
at> hostname
at> <EOT>
job 4 at Fri Dec  8 10:00:00 2023

注意

(1)这里是24小时制的,所以10:00指的是上午10点,如果想指定下午10点,则要写成22:00。

(2)写时间最多只能精确到分,不能精确到秒。

这里上午用am表示,下午用pm表示。例如,要在2023年12月08日下午10点执行hostname命令

复制代码
[root@jiayi ~]# at 10pm 2023-12-08
warning: commands will be executed using /bin/sh
at> hostname
at> <EOT>
job 5 at Fri Dec  8 22:00:00 2023

at也支持某天之后的某个时间点运行一个命令。例如,要在3天之后的下午4点执行,hostname命令

复制代码
[root@jiayi ~]# at 4pm + 3days
warning: commands will be executed using /bin/sh
at> hostname
at> <EOT>
job 6 at Sun Dec 10 16:00:00 2023

这里"+"两边有没有空格都可以,days可以换成weeks,表示3周之后的下午4点

如果想在第二天的下午4点执行hostname命令,可以用关键字tomorrow,如果使用关键字tomorrow,则不需要加"+"

复制代码
[root@jiayi ~]# at 4pm tomorrow
warning: commands will be executed using /bin/sh
at> hostname
at> <EOT>
job 7 at Fri Dec  8 16:00:00 2023

如果要表示几分钟或几小时之后,可以用关键字now。

如果想1分钟之后删除/tmp下面所有的内容

复制代码
[root@jiayi ~]# at now+1minutes
warning: commands will be executed using /bin/sh
at> rm -rf /tmp/*
at> <EOT>
job 9 at Thu Dec  7 14:17:00 2023

下面来验证一下,先查看/tmp

复制代码
[root@jiayi ~]# ls /tmp/*
/tmp/anaconda.log  /tmp/dnf.librepo.log     /tmp/ks-script-up4s6qy1  /tmp/program.log
/tmp/dbus.log      /tmp/ks-script-qggxy3gb  /tmp/packaging.log       /tmp/sensitive-info.log

等一会再次查看/tmp中的内容

复制代码
[root@jiayi ~]# date ; ls /tmp/
2023年 12月 07日 星期四 14:17:13 CST
[root@jiayi ~]# 

可以看到,/tmp中的内容已经被清空

到现在为止已经做了很多个at计划任务了,现在来查看一下有多少个了。通过atq或at -1都可以查看

复制代码
[root@jiayi ~]# at -l
2    Fri Dec  8 14:10:00 2023 a root
3    Fri Dec  8 14:11:00 2023 a root
4    Fri Dec  8 10:00:00 2023 a root
5    Fri Dec  8 22:00:00 2023 a root
6    Sun Dec 10 16:00:00 2023 a root
7    Fri Dec  8 16:00:00 2023 a root
8    Thu Dec  7 16:16:00 2023 a root

可以看到,每个at计划任务前都有一个编号。如果要删除某个at计划任务,可以用如下命令

复制代码
atrm N 
或
at ‐d N

这里N指的是atq查看结果中前面的编号

假设现在要删除编号为8的at计划任务

复制代码
[root@jiayi ~]# at -d 8
[root@jiayi ~]# at -l
2    Fri Dec  8 14:10:00 2023 a root
3    Fri Dec  8 14:11:00 2023 a root
4    Fri Dec  8 10:00:00 2023 a root
5    Fri Dec  8 22:00:00 2023 a root
6    Sun Dec 10 16:00:00 2023 a root
7    Fri Dec  8 16:00:00 2023 a root

再删除编号为3到7的这些at计划任务

复制代码
[root@jiayi ~]# atrm {3..7}
[root@jiayi ~]# at -l
2    Fri Dec  8 14:10:00 2023 a root

查看at计划任务的具体内容,命令如下

复制代码
at ‐c N

查看第10个at计划任务的内容

复制代码
[root@jiayi ~]# at -c 10 | tail -3
${SHELL:-/bin/sh} << 'marcinDELIMITER44b4a4c7'
poweroff
marcinDELIMITER44b4a4c7

这里at -c 10的结果太多,所以通过管道传递给tail 命令,获取最后3行的内容。可以看到,第一个at计划任务中执行的命令是poweroff

任何用户都是可以创建at计划任务的,下面使用jiayi用户随便创建一个at计划任务,例如,要在3小时之后执行hostname命令

复制代码
[jiayi@jiayi ~]$ at now+3hours
warning: commands will be executed using /bin/sh
at> hostname
at> <EOT>
job 12 at Thu Dec  7 18:19:00 2023
[jiayi@jiayi ~]$ 
[jiayi@jiayi ~]$ at -l
12    Thu Dec  7 18:19:00 2023 a jiayi

这里是可以正常创建的,如果要禁止哪个用户创建at计划任务,只要把这个用户名写入/etc/at.deny中即可,一行一个用户。下面练习禁止 jiayi用户创建at计划任务,使用root做如下操作

复制代码
[root@jiayi ~]# echo jiayi > /etc/at.deny 
[root@jiayi ~]# cat /etc/at.deny 
jiayi

凡是出现在/etc/at.deny文件中的用户都是不允许创建at计划任务的。切换到jiayi用户创建at计划任务

复制代码
[jiayi@jiayi ~]$ at now+1hours
You do not have permission to use at.

可以看到,jiayi用户已经没有权限创建了。

如果想继续允许jiayi用户创建at计划任务,有以下两种方法。

(1)把tom用户从/etc/at.deny中删除。

(2)把 tom用户添加到/etc/at.allow中。

/etc/at.allow这个文件默认不存在,需要创建出来,且 at.allow 的优先级要高于at.deny,所以 jiayi如果同时出现在这两个文件中,那么at.allow生效

下面设置jiayi用户可以创建at计划任务,使用root做如下操作

复制代码
[root@jiayi ~]# echo jiayi > /etc/at.allow
[root@jiayi ~]# cat /etc/at.allow
jiayi
[root@jiayi ~]# cat /etc/at.deny 
jiayi

现在jiayi用户在at.allow 和 at.deny中都存在,at.allow生效,所以 jiayi用户是可以创建at计划任务的。切换到jiayi用户创建at计划任务

复制代码
[jiayi@jiayi ~]$ at now+1hours
warning: commands will be executed using /bin/sh
at> hostname       
at> <EOT>
job 13 at Thu Dec  7 16:21:00 2023
[jiayi@jiayi ~]$ at -l
12    Thu Dec  7 18:19:00 2023 a jiayi
13    Thu Dec  7 16:21:00 2023 a jiayi

2.crontab

at计划任务是一次性的,执行完成就结束,不会重复执行。如果想定期执行某个任务,例如,每周日凌晨2点执行一个命令,这时就要用到crontab了。

查看当前用户是否有 crontab计划任务,可以用crontab-1命令。如果要查看其他用户是否有crontab计划任务,可以用"crontab -1-u用户名"命令,不过-u选项只有root才能用.

使用root用户查看自己有没有crontab计划任务

复制代码
[root@jiayi ~]# crontab -l
no crontab for root

使用root用户查看jiayi用户是否有crontab计划任务

复制代码
[root@jiayi ~]# crontab -l -u jiayi
no crontab for jiayi

创建crontab计划任务的命令是crontab -e,如果为其他用户创建crontab计划任务,则用"crontab -e -u用户名"命令。当使用crontab-e命令时,会打开一个临时文件,用与vim 一样的语法来编辑此文件即可。先按【i】键进入插入模式,编辑完成之后,按【Esc】键退回到命令模式,在末行模式中输入"wq"保存退出。在此文件中凡是以"#"开头的,都是注释行。

crontab定义计划任务的语法如下

复制代码
分 时 天 月 周 命令

注意

因为在crontab中使用的并非系统的PATH变量,所以此处语法中要执行的命令最好能加上路径,例如,要执行ifconfig命令,则写作/sbin/ifconfig;要执行hostname命令,则写作bin/hostname。命令的路径可以通过which命令来查询。

几个时间单位的意义如下。

(1)分:几点几分的分。

(2)时:几点,24小时制。

(3)天:几号。

(4)月:几月份。

(5)周:星期几。

这几个时间单位可以用空格,也可以用【Tab】键来分隔。

如果不考虑某个时间单位,例如,不管今天是几号,只要不是周末我们就上班,不考虑"天"的情况下,那么可以用*表示。

这里每个时间点都可以写多个值,用英文逗号","隔开,例如,在分的位置写"0,1.,5,10",表示0分、1分、5分、10分。

也可以用横杠"-"表示"到"的意思,例如,在分的位置写"0-10",表示0到10分。

这里"0-10"的完整写法是"0-10/1",表示从0分到10分的每一分钟,从0开始每次增加1,然后到10。如果表示"每N分钟",则写成"0-10/N",例如,0到10中每2分钟,则写成"0-10/2",表示0分、2分、4分、6分、8分、10分。

每天上午7点整执行hostname命令

复制代码
0 7 * * * hostname

每周一到周五的上午7点整执行hostname命令

复制代码
0 7 * * 1-5 hostname

也可以用逗号隔开指定日期

第一季度中每周一到周五的上午7点整执行hostname命令

复制代码
0 7 * 1-3 1-5 hostname

一年的第一季度是1到3月份,这里分、时、月、周(没有天)是"或"的关系,这4个时间单位必须都满足才能执行hostname命令

所以,5月份的周三上午7点整是不会执行hostname命令的,因为"月"没有满足条件

第一季度中每月上旬的上午7点整执行hostname命令

复制代码
0 7 1-10 1-3 * hostname

一年的第一季度是1到3月份,每月上旬是1到10日,这里分、时、天、月(没有周)是"或"的关系,这4个时间单位必须都满足才能执行hostname命令

所以,5月8日上午7点整是不会执行hostname命令的,因为"月"没有满足条件。大家要记住,"天"和"周"是"或"的关系,即

(1)分、时、月、周同时满足了,即使"天"不满足条件,也会执行指定的命令。

(2)分、时、天、月同时满足了,即使"周"不满足条件,也会执行指定的命令。

在5个时间点都写的情况

复制代码
0 7 1-10 1-3 1-5 hostname 

这里天和周的位置都写了,本句的意思并不是说每年1到3月份的上旬,且要满足周一到周五的上午7点整才执行hostname命令

这句的意思是每年的1到3月份这3个月,每月1到10日或周一到周五(二者满足其一),上午7点整都会执行hostname命令。这条其实综合了上面练习3和练习4中的意思

现在最终的crontab计划任务内容如下

复制代码
[root@jiayi ~]# crontab -l
0 7 * * * hostname
0 7 * * 1-5 hostname
0 7 * 1-3 1-5 hostname
0 7 1-10 1-3 * hostname
0 7 1-10 1-3 1-5 hostname 

如果要编辑 crontab计划任务,通过crontab -e来重新编辑;如果要删除,执行 crontab -r命令即可

复制代码
[root@jiayi ~]# crontab -r
[root@jiayi ~]# crontab -l
no crontab for root

普通用户也是可以创建crontab计划任务的,和上面的at一样禁用写入/etc/cron.deny,允许写入/etc/cron.allow也一样需要自己创造出来

系统中也自带一些crontab计划任务,在/etc 中存在几个以cron开头的目录

复制代码
[root@jiayi ~]# ls /etc/cron*
/etc/cron.deny  /etc/crontab

/etc/cron.d:
0hourly  raid-check

/etc/cron.daily:
logrotate

/etc/cron.hourly:
0anacron

/etc/cron.monthly:

/etc/cron.weekly:

每天都会执行一次/etc/crondaily中的脚本,每小时都会执行一次/etc/cron.hourly中的脚本,每月都会执行一次/etc/cron.monthly中的脚本,每周都会执行一次/etc/cron.weekly中的脚本

相关推荐
A小辣椒20 小时前
TShark:Wireshark CLI 功能
linux
A小辣椒1 天前
TShark:基础知识
linux
AlfredZhao1 天前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao2 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334662 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪2 天前
linux 拷贝文件或目录到指定的位置
linux
大树883 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠3 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质3 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush43 天前
嵌入式linux学习记录十四、术语
linux·嵌入式