Linux 调度周期性任务
如果需要在操作系统中安排定期自动执行的任务或程序,可以通过以下工具完成。
at
用于安排单次任务在指定的时间执行。at通常用于哪些只需要执行一次的任务。
at 配置文件
at工具的使用,依赖于一个后台守护进程atd(at daemon),在以systemd作为初始化进行的操作系统中,一般将这个守护进程交给systemd进行托管。
ehigh@ubuntu:~$ systemctl cat atd.service
# /lib/systemd/system/atd.service
[Unit]
Description=Deferred execution scheduler
Documentation=man:atd(8)
After=remote-fs.target nss-user-lookup.target
[Service]
ExecStartPre=-find /var/spool/cron/atjobs -type f -name "=*" -not -newercc /run/systemd -delete
ExecStart=/usr/sbin/atd -f
IgnoreSIGPIPE=false
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
at 创建任务
atd服务正在运行是at命令正常工作的前提。通过命令行创建计划任务时,会在 /var/spool/at(centos)或/var/spool/cron/atjobs(ubuntu)
目录下生成对应的文件,当计划任务执行完成后,这个对应的文件也会被删除。
交互式
使用at创建单次执行的计划任务时,需要指定执行时间,然后回进入一个特殊的提示符,可以在这个提示符下输入要执行的命令。输入完成后使用 ctrl+d
进行退出。
格式
at 具体时间
at> 需要执行的具体内容
例如:
at 14:35
warning: commands will be executed using /bin/sh
at> echo "hello world" > /tmp/test.1
at> <EOT> # 按crtl+d结束
通过管道
at也支持管道符,如果不想使用这个交互式的方式,可以借助管道符来完成。
格式:
echo "需要执行的内容" | at 具体的时间
例如:
echo "ls -l" | at 16:58
at 时间格式
绝对时间
指定一个精确的时间点,格式通常是 HH:MM。例如,at 14:00 会在今天下午两点执行任务。如果指定的时间已经过去,则默认为第二天的该时间。
例如:
at 20:00
相对时间
-
分钟:例如,at now + 15 minutes 将在从现在开始的15分钟后执行任务
-
小时:例如,at now + 1 hour 将在1小时后执行任务
-
天:例如,at now + 2 days 将在两天后执行任务
具体日期
使用at工具的时候,还可以指定具体的日期,格式通常是 MMDDYY 或 YYYY-MM-DD。
例如:
at 17:00 2022-07-19
查看计划任务
方法一:通过 at的 -l 选项实现,可以查看哪些计划任务还没有被执行,执行了的计划任务使用 -l 是没法看到的。
at -l
方法二:通过 atq查看,atq用于列出当前用户的计划任务
atq
取消计划任务
需要先通过at或者atq查看对应的作业编号。
方法一:通过at的 -d 选项取消对应的计划任务
at -d 编号
方法二:通过 artm取消指定的人去
artm 编号
cron
cron用于周期性自动执行的任务或程序,cron提供了一个叫作crontab的命令行工具来管理cron任务。cron时根据配置文件中定义的时间表来执行用户指定的命令或脚本
cron 配置文件
service 文件
crontab命令行工具的使用依赖于cron的守护进程(或有时被命名为cronie, crond等其他名称)的正常运行。
在以systemd作为初始化进程的操作系统中,一般将cron的守护进程交给systemd进行托管
ehigh@ubuntu:~$ systemctl cat cron.service
# /lib/systemd/system/cron.service
[Unit]
Description=Regular background program processing daemon
Documentation=man:cron(8)
After=remote-fs.target nss-user-lookup.target
[Service]
EnvironmentFile=-/etc/default/cron
ExecStart=/usr/sbin/cron -f $EXTRA_OPTS
IgnoreSIGPIPE=false
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
用户级配置文件
定义: 每个用户都可以有自己的 crontab 文件,用于定义该用户的定期任务。
编辑: 用户可以通过运行 crontab -e 命令来编辑自己的 crontab 文件。
位置: 用户的 crontab 文件通常存储在 /var/spool/cron/crontabs/ 目录下和用户名同名,但不应直接编辑这些文件,而是使用 crontab 命令。
权限: 用户可以仅为自己安排任务,前提是 cron 守护进程对他们有执行权限
系统级配置文件
定义: 系统级配置文件是为系统整体定义的任务,而不是为特定用户定义的。
权限: 编辑系统级的 cron 配置文件需要管理员权限。
-
/etc/crontab:定义了执行计划任务的shell和指定了PATH变量
-
/etc/cron.d/:用于存放单独的 cron 配置文件
-
/etc/cron.hourly:存放按小时执行的脚本(脚本需要有执行权限且无后缀)
-
/etc/cron.daily:存放按天执行的脚本(脚本需要有执行权限且无后缀)
-
/etc/cron.weekly:存放按周执行的脚本(脚本需要有执行权限且无后缀)
-
/etc/cron.monthly/:存放按月执行的脚本(脚本需要有执行权限且无后缀)
例如:如果有一个脚本需要每天执行一次,可以将这个脚本加上可执行权限后,放入etc/cron.daily目录下即可。
创建用户计划任务
通过运行 crontab -e 命令来编辑自己的 crontab 文件,
配置文件格式
使用 crontab -e
打开 /var/spool/cron/crontabs/下以用户名命名的文件后
,需要按照一定的格式进行编辑,计划任务才会生效。具体的格式如下:
* * * * *
- - - - -
| | | | |
| | | | +----- 星期中星期几 (0 - 6) (星期天 为0)
| | | +---------- 月份 (1 - 12)
| | +--------------- 一个月中的第几天 (1 - 31)
| +-------------------- 小时 (0 - 23)
+------------------------- 分钟 (0 - 59)
特殊格式
1、星号:表示每
例如:每天凌晨2:00执行一次指定的任务
0 2 * * * ls
2、/num:表示去确定的时间
例如:每十分钟执行一次任务
*/10 * * * * ls
3、离散值:x,y,z,
例如:表示每天凌晨2点,5点。六点执行一次任务
0 2,5,6 * * * ls
4、连续值:x-y
例如:每月1-5号执行一次任务
0 0 0 1-5 * ls
例如:创建一个计划任务,每天凌晨三点执行数据库备份呢脚本:
crontab -e
0 3 * * * /bin/bash /home/ehigh/work/job/MySQLBack.sh >> /dev/null
说明:默认是以运行crontab进程的用户身份来创建,如果想要以指定的用户身份创建计划任务,可以用 -u 参数
来指定用户名。
例如:
sudo crontab -u root -e
查看计划任务
计划任务创建好后,可以通过 -l 参数来查看,如果要查看别人的计划任务,在权限允许的情况下,可以加 -u 参数来指定用户。
例如:查看当前用户的计划任务
crontab -l
例如:查看root用户的计划任务
crontab -u root -l
取消计划任务
方法一:通过 -r 选项移除当前用户所有的计划任务
crontab -r
方法二:通过 -e 参数编辑配置文件,注释指定计划任务
crontab -e
systemd 定时器
systemd提供的定时器也可以完成at和cron的功能,并且timer提供了更强大的功能和更灵活的配置选项
定时器配置方法
1、创建service服务定义要执行的任务。
2、创建一个 .timer 文件,与服务文件同名,定义何时执行任务。
3、启动和启用定时器
周期性执行任务
例如:每隔10秒钟调用一次指定的接口
(1)创建service文件
ehigh@ubuntu:~$ systemctl cat delRule.service
# /etc/systemd/system/delRule.service
[Unit]
Description=Call the interface once every 10 seconds
[Service]
Type=oneshot
ExecStart=/usr/bin/curl http://192.168.0.112/EHCommon/construction/Construction/delRule
- 启动类型需要指定为oneshot
(2)创建同名的 .timer文件
ehigh@ubuntu:~$ systemctl cat delRule.timer
# /etc/systemd/system/delRule.timer
[Unit]
Description=Runs my custom script every 10 seconds
[Timer]
OnBootSec=10sec
OnUnitActiveSec=10sec
AccuracySec=5s
[Install]
WantedBy=timers.target
-
OnBootSec:表示系统启动后10秒,定时器首次触发。
-
OnUnitActiveSec:表示定时器每10秒触发一次。
-
AccuracySec:用于调整定时器精度,不指定就是60s,这里表示实际触发时间可以在计划时间前后最多5秒的范围内。
(3)加载配置
systemctl daemon-reload
(4)启动timer,设置开机启动
systemctl enable delRule.timer --now
单次执行任务
system的定时器单词执行任务时,效果等同于at
1、创建service文件,指定要执行的命令
2、创建timer文件,文件名要和service文件名同名
[Unit]
Description=Timer for one-time task
[Timer]
OnCalendar=2023-04-01 12:00:00
Persistent=true
[Install]
WantedBy=timers.target
-
OnCalendar:指定具体的日期和时间
-
Persistent:如果错过了计划时间,下次启动时将尽快运行
3、加载service配置
systemctl daemon-reload
4、设置启动
systemctl enable XXX.timer --now
三个工具对比
at 用于安排单次任务,不能用于周期性任务。
cron 可以周期性执行任务,但时间间隔的最小单位是一分钟。
systemd 定时器具有 at 和 cron 的功能,可以自定义执行计划任务的间隔时间,甚至短于一分钟,并提供更多高级功能。