Linux crontab

crontab​ 是一个用于管理用户的定时任务调度工具。它允许用户设置在特定时间自动运行的命令或脚本,常用于定期执行备份、系统监控、数据处理等任务。

atd – 执行一次性命令的守护进程

生活中,我们有太多场景需要使用到闹钟,比如早上 7 点起床,下午 4 点开会,晚上 8 点购物,等等。

在 Linux 系统里,我们同样也有类似的需求。比如我们想在凌晨 1 点将文件上传服务器,或者在晚上 10 点确认系统状态,等等。

但我们不可能一直守在电脑前,毕竟我们也需要下班/睡觉,还要陪对象(new一个也行)。而且即使在上班期间,如果到点了还需要人工操作,未免效率太低了。

at​ 命令就是为这个需求而诞生的。使用 at​ 命令,你可以在特定时间自动完成你所设定的任务,也可以实现自动化,非常方便快捷!

at安装

一般来讲,大部分 Linux 发行版都已经安装了 at​ 命令,不确定的话可以使用 at -V​ 命令查看,如果有版本返回,说明就可以正常使用 at​ 命令。

at -V # 查看版本

atd服务启动

你可以使用 systemctl​ 命令启用 atd​ 服务并将它们设置为从现在开始自动启动

1
sudo systemctl enable --now atd

at命令基本用法

  • 语法

    at [options] [time]

  • 选项

    -f 指定包含具体指令的任务文件

    -q 指定新任务的队列名称

    -l 显示待执行任务的列表

    -d 删除待执行的任务

    -m 任务执行完后向用户发送邮件

  • time:时间格式

    HH:MM

    HH:MM YYYY-MM-DD 或者 HH:MM MM/DD/YYYY

    HH:MM[am|pm] [month] [date]

    HH:MM[am|pm] + number [ minutes | hours | days | weeks | months | years ]

示例

  1. echo “echo ‘hello’ >> /home/zyming/at-test.txt” | at 3:30 am 10/01/2024 或者 echo “echo ‘hello’ >> /home/zyming/at-test.txt” | at 3:30 am 2024-10-01

使用 at 命令交互性安排任务

at 11:00 am

echo “hello” >> /home/zyming/at-test.txt

ctrl+d退出交互环境

使用 at 命令安排任务

echo “echo ‘hello again’ >> /home/zyming/at-test.txt” | at now + 1 minutes

查看 at 任务队列

at -l <=> atq

从任务队列中删除任务

atrm <任务编号>

根据at任务列表选择删除的内容

atq && read -p “输入待查看at任务编号:” n && atrm $n

查看at任务内容

at -c <任务编号> | tail -n +71 | head -n -2

或者

通过管理员权限查看 /var/spool/at中保存的内容

(sudo ls /var/spool/at | awk ‘{print NR “:” 1}’) && read -p “需要查看第几个at任务:” n && sudo tail -n+71 /var/spool/at/(sudo ls /var/spool/at | head -n $n | tail -n 1)| head -n -2

根据at任务列表选择查看的内容

atq && read -p “输入待查看at任务编号:” n && (at -c $n | tail -n +71 | head -n -2)

batch –系统空闲时执行的后台任务

batch是利用at来进行指令下达的,它会在cpu的工作负载小于0.8时,马上执行用户下达的工作任务。

  1. uptime # 查看当前负载(load average)
  2. bc -lq <<< “scale=100000; 4*a(1)” &
  3. bc -lq <<< “scale=100000; 4*a(1)” & # 小于0.8,则继续增加负载
  4. uptime # 查看当前负载(load average)
  5. batch > /usr/bin/updatedb
  6. date; atq # 查看此时是否执行(当前时间超过计划时间)
  7. jobs > kill -9 %?
  8. uptime;atq # 查看执行与否

crond – 执行周期性命令的守护进程

crontab安装与检查

sudo yum list crontabs # 检查是否安装

crontab -V # 查看版本

sudo yum install crontab

crontab服务启动与关闭

systemctl start crond # 启动

systemctl stop crond # 关闭

systemctl enable crond # 开机自启

全局配置文件(crontab每分钟检测一次/etc/crontab和/var/spool/cron)

cron.hourly # 是每个小时执行一次的job

cron.daily # 是每天执行一次的job

cron.monthly # 是每月执行一次的job

cron.d # 是系统自动定期需要做的任务

1
cat /etc/cron.d/0hourly
1
2
3
4
5
# Run the hourly jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly

crontab # 是设定定时任务执行文件

1
cat /etc/crontab
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed

crontab.deny # 文件用于控制不让哪些用户使用crontab

用户配置文件

每个用户都有自己的cron配置文件,通过crontab -e就可以编辑。

时间配置测试网站

image-geczmu2

星号():代表所有可能的值,例如month字段如果是星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。
逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9”
中杠(-):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6”
正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。同时正斜线可以和星号一起使用,例如/10,如果用在minute字段,表示每十分钟执行一次。

定时任务实例

  1. 每月每天凌晨3点30分和中午12点30分执行test.sh脚本

    30 3,12 * * * /home/test.sh

  2. 每月每天每隔6小时的每30分钟执行test.sh脚本

    /30 /6 * * * /home/test.sh

  3. 每月每天早上8点到下午18点每隔2小时的每30分钟执行test.sh脚本

    /30 8-18/2 * * * /home/test.sh

  4. 每月每天晚上21点30分执行test.sh脚本

    30 21 * * * /home/test.sh

  5. 每月1号、10号、22号凌晨4点45分执行test.sh脚本

    45 4 1,10,22 * * /home/test.sh

注意

某些时候天和星期一起设置会冲突

查询/删除当前用户定时任务

crontab -l / crontab -r

可唤醒停机期间的工作任务(anacron)

  1. 目的

    anacron不是crontab的替代物,它是一个程序,针对非24小时一直启动linux系统的crontab执行,以及由于特殊原因超过预计时间没被执行的定时任务而提出

anacron与/etc/anacrontab

anacron是一个程序,放到了/etc/cron.hourly,得以每个小时运行一次。

anacrontab的执行流程(以cron.daily为例)

  1. 分析/etc/anacrontab,得到cron.dailly的执行周期为1天;
  2. 由/var/spool/cron.daily得到上次执行anacrontab的时间戳;
  3. 若该时间戳与目前时间相差超过了1天,那么准备执行指令;
  4. 根据/etc/anacrontab中设定的delay in minutes和START_HOURS_RANGE=3-22,得出指令的运行时间应当是在当天的3:00到22:00之间,每个小时的前五分钟内随机执行,若不在此时间范围以内,则在第二天的3:00开始执行;
  5. 执行完 run-parts /etc/cron.daily,anacrontab整个流程结束。

总结:anacrontab每个小时去检测时间戳的差距,可以使得cron.daily中的任务每天执行一次,而由于其执行周期为1小时,因此开机后的1小时左右系统会进行一定的检测工作。