作为一名运维人员,我们经常需要将某些命令或脚本放入计划任务中去执行。
- 例如,服务器的访问量白天一般较大,在服务器承受着巨大访问压力的同时对其进行全量备份是不合适的,这时就可以考虑将备份工作放入系统计划任务,这样系统可以在夜间服务器访问量小时自动执行备份任务。
- 又如,我们需要定期执行服务器之间的数据同步操作,此时也要使用计划任务功能。Linux系统为我们准备了多种计划任务,一种是at一次性计划任务,一种是cron周期性计划任务,还可以通过systemd定制计划任务。
1、at一次性计划任务
使用at命令设置一次性计划任务前需要确保atd服务是开启的,否则计划任务不会被执行。即使用systemctl start atd开启服务,并使用systemctl enable atd确保该服务开机自启动。
at命令可以使用的时间格式有很多:
- at 小时:分钟(默认在当天的某个时间执行计划任务)、
- at 4pm + 3 days(指定某一天的某个时间执行计划任务,此处为3天后的下午4点)、
- at 时间 年-月-日(指定在某个具体的年月日及时间执行计划任务)
at 命令
- 描述:在指定的时间执行特定命令。
- 语法:at 时间
-m 当计划任务执行结束后发送邮件给用户。
-l 查看计划任务。
-d 删除计划任务。
-c 查看计划任务的具体内容。(concreteness)
at -l # 查看计划任务
at -c 1 # 查看编号为1的计划任务的具体内容
at -d 1 # 删除编号为1的计划任务
# 再2023-10-08下午5点 执行关机计划任务
at 17:00 2023-10-08 # 再2023-10-08 17:00 执行一次性计划任务
at > shutdown -h now # 执行关机任务
at > Ctrl + D # Ctrl + D 退出
2、cron周期性计划任务
使用cron确定计划任务前需要确保crond服务是开启的,否则计划任务不会被执行,即需要使用systemctl start crond开启服务,并使用systemctl enable crond确保该服务开机自启动。
用户的cron计划任务文件格式描述参考表2-10:
- 使用24小时制时,分范围为00~59,时范围为00~23,日范围为1~31,月范围为1~12,周范围为0~7(其中0或7都可以表示周日)。
- 如果需要指定时间段:
-
- 可以使用横杠(-):表示一段连续的时间,
- 使用逗号(,)表示若干不连续的时间,
- 使用星号(*)表示所有时间,
- 使用斜杠(/)表示间隔时间。
crontab 命令
- 描述:为每个用户维护周期性的计划任务文件。
- 用法:crontab [-u 用户] [-l|-r|-e]
-
- -u 指定计划任务的用户,默认为当前用户。
- -l 查看计划任务。
- -r 删除计划任务。
- -e 编辑计划任务。
- -i 使用-r删除计划任务时,要求用户确认。
crontab -e # 为当前用户设置计划任务,内容如下:
# 每周五23时23分执行日志备份任务
23 23 * * 5 tar -czf log.tar.bz2 /var/log
# 每3小时整点检查用户登录情况,追加到/var/log/login.log文件中(该文件会被自动创建)
00 */3 * * * who >> /var/log/login.log
# 每周三、周五10时将系统内存信息发送到自己的邮箱
00 10 * * 3,5 free | mail -s "Mem" root@localhost
# 查看root用户的计划任务
crontab -l -u root
# 每天下午17:30分关闭firewalld防火墙
crontab -e
30 17 * * * /usr/bin/systemctl stop firewalld
# 每隔3天删除/media目录中后缀名为.txt文件
* * 3 * * /usr/bin/rm -rf /media/*.txt
# 每周日晚上的22:00将/etc/passswd文件复制到/mnt目录中
00 22 * * 7 /usr/bin/cp /etc/passwd /mnt
# 删除root用户计划任务
crontab -r
crontab -l
3、计划任务权限
为了使用户不要随意定义计划任务,管理员可以进行ACL访问控制
- at计划任务的控制文件分别为/etc/at.allow和/etc/at.deny,默认at.allow不存在。
- cron计划任务的控制文件分别为/etc/cron.allow和/etc/cron.deny,默认cron.allow不存在。
在这些控制文件中,仅需要写入用户名,格式为一行一个用户名。
- 当allow文件存在时,仅在allow文件中出现的用户可以使用对应的计划任务;
- 如果allow文件与deny文件中同时存在一样的用户,则仅出现在allow中的用户可以使用计划任务;
- 如果没有allow文件而仅有deny文件,则所有出现在deny中的用户无法使用计划任务,其他用户均可使用计划任务。
当非法用户使用crontab -e编辑计划任务时,系统将提示如下内容
4、通过systemd定制计划任务
crond周期性计划任务的最小时间单位为分,如果需要比分更细粒度的计划任务该怎么定义呢?systemd提供了一个timer计时器功能,通过该功能可以设置更加丰富的计划任务,timer计时器可以处理微秒级别的计划任务,其时间单位可以是us(微秒)、ms(毫秒)、s(秒)、m(分)、h(时)、d(日)、w(周)、M(月)、y(年),如果没有指定时间单位,则默认单位是s(秒)。
timer文件中必须包含一个[timer]配置段,该配置段中包含多个计划任务相关选项,常用选项如下表:
创建计时器的方法是在 /usr/lib/systemd/system/
目录或 /etc/systemd/system/
目录中:
- 创建一个名称后缀为.timer的文件,
- 每个计时器都需要配备一个按时间计划执行的任务,默认计时器会找到一个同的.service文件并激活其中的服务,比如example.timer会自动匹配对应的example.service文件。
- 除此之外也可以在timer计时器文件中通过Unit来指定需要激活的服务。
下面编写一个使用tar命令将/root目录打包备份到/opt目录中的backup.service文件,然后编写一个同名的backup.timer文件(扩展名不同),通过timer计时器定时触发计划任务,使backup.servce被激活并执行。
# 编写备份服务
vim /etc/systemd/system/backup.service
[Unit]
Description=backup root directory
[Service]
# 通过 tar 命令将/root/目录打包并压缩,打包压缩后的文件放到/opt目录中
ExecStart=tar -czf /opt/root.bak.tar.gz /root
# 编写计时器
vim /etc/systemd/system/backup.timer
[Unit]
Description=backup timer
[Timer]
# 每天 11:02 开始,每隔3分钟将同名的backup.service激活,执行一次备份任务
# 也可以通过“Unit=”形式定义任何其他需要激活并执行的任务
OnCalendar=11:2/3
[Install]
WantedBy=multi-user.target
systemctl daemon-reload # 重新加载所有systemd配置
systemctl start backup.timer # 立刻启动backup计时器
systemctl enable backup.timer # 设置计时器为开机自启动
systemctl status backup.timer # 查看计时器任务
# 没做出来
Nov 03 23:06:55 Lemon systemd[1]: [/etc/systemd/system/backup.service:5] Executable path is not absolute, ignoring: tar
Nov 03 23:06:55 Lemon systemd[1]: backup.service lacks both ExecStart= and ExecStop= setting. Refusing.
Nov 03 23:06:55 Lemon polkitd[692]: Unregistered Authentication Agent for unix-process:66753:765161 (system bus name :1.