月落汀兰头像
关注
Linux 定时任务踩坑合集!at 一次性任务 + crontab 循环定时完整实操封面图

Linux 定时任务踩坑合集!at 一次性任务 + crontab 循环定时完整实操

Linux 计划任务管理

一、一次性计划任务 at(只执行1次的定时任务)

核心作用

at 用来设置未来某一个时间点只运行一次的任务。 举例:5分钟后自动备份文件、今晚23点自动关机,只执行一次,执行完任务自动消失。 底层依赖后台守护进程 atd,没有这个进程at任务不会自动运行。

1. atd 服务安装、查看状态

# 安装at工具包,系统最小化安装默认不带at
[root@centos7 ~]# yum install at

逐段解释:

  • yum:CentOS7系统软件包管理器,用来下载、安装rpm软件
  • install:yum子命令,代表执行安装操作
  • at:要安装的软件包名称,包含at、atq、atrm全套定时工具
# 查看atd后台服务运行状态
[root@centos7 ~]# systemctl status atd

逐段解释:

  • systemctl:CentOS7统一管理系统服务的工具
  • status:子命令,查看指定服务当前运行状态
  • atd:一次性定时任务的后台守护进程名,所有at任务靠它调度执行

输出字段详细解释:

● atd.service - Job spooling tools
# 服务名称:atd服务,作用:管理队列定时任务
   Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled; vendor preset: enabled)
# Loaded:服务配置文件路径;enabled=开机自启;系统出厂默认开启
   Active: active (running) since Wed 2022-12-21 16:54:08 CST; 3min 22s ago
# Active:running=正在运行;显示启动时间、已经运行多久
 Main PID: 1184 (atd)
# Main PID:守护进程的系统进程号1184
    Tasks: 1
# 当前进程内部线程数量1个
   CGroup: /system.slice/atd.service
           └─1184 /usr/sbin/atd -f
# 进程实际运行程序路径 /usr/sbin/atd -f
Dec 21 16:54:08 centos7.linux.com systemd[1]: Started Job spooling tools.
# 系统日志:系统启动成功拉起atd服务

2. at 命令基础语法

语法:at <时间格式>

工作逻辑:输入这条命令后,终端进入任务编辑模式,输入要执行的命令,按下 Ctrl+D 保存任务,atd到时间自动执行。

示例1:5分钟后执行单行命令

[root@centos7 ~]# at now +5 minutes
# 进入at编辑模式
at> echo hello world > /tmp/hello.log
# 输入完指令,按Ctrl+D保存任务,文档中<EOT>就是Ctrl+D生成的结束标记
at> <EOT>
job 1 at Wed Dec 21 17:09:00 2022

逐行拆解:

  1. at now +5 minutes
    
    • at:进入定时任务编辑模式
    • now:当前系统时间
    • +5 minutes:往后推迟5分钟 整体含义:5分钟后执行下面输入的命令
  2. echo hello world > /tmp/hello.log
    
    • echo hello world:输出字符串 hello world
    • >:输出重定向符号,不打印到屏幕,写入文件
    • /tmp/hello.log:临时日志文件,存放输出内容
  3. Ctrl+D:结束输入,保存任务,系统分配任务编号 job 1

  4. job 1 at xxx:返回信息,任务ID=1,执行时间

示例2:通过脚本文件批量执行多条命令

适合多条复杂指令,不用手动一行行输入at交互界面

# 1. 创建脚本文件
[root@centos7 ~]# vim myscript.sh

脚本内容:

#!/bin/bash
date >> /tmp/myscript.log
echo hello myscript >> /tmp/myscript.log

脚本逐行解释:

  • #!/bin/bash:脚本声明,指定用bash解释器运行文件,必须写在第一行
  • date:输出当前系统时间;>> 追加写入,不覆盖原有文件内容
  • echo hello myscript:输出文本,追加写入日志
# 方式1:输入重定向,读取脚本创建任务
[root@centos7 ~]# at now +5 minutes < myscript.sh 
job 2 at Wed Dec 21 17:10:00 2022

参数解释:

  • < myscript.sh:输入重定向,把myscript.sh里面所有命令导入at,替代手动输入
# 方式2:使用-f参数指定脚本文件
[root@centos7 ~]# at now +100 minutes -f myscript.sh 
job 3 at Wed Dec 21 18:46:00 2022

参数解释:

  • -f:file缩写,指定要读取的脚本文件,和 < 重定向效果完全一致

支持的时间格式(timespec)全部说明

  1. now +5 hours:当前时间往后5小时
  2. teatime tomorrow:明天16点(teatime固定代表16:00)
  3. noon +4 days:4天后中午12点(noon固定12点)
  4. 5 pm august 3 2016:2016年8月3日下午5点 时间规则存放文档:/usr/share/doc/at/timespec,可打开查看全部写法

3. at 配套管理命令(查看/指定队列/查看任务详情/删除任务)

(1)at -l / atq 查看所有等待执行的任务

两条命令功能完全等价

[root@centos7 ~]# at -l
1   Wed Dec 21 17:09:00 2022 a root
2   Wed Dec 21 17:10:00 2022 a root
3   Wed Dec 21 18:46:00 2022 a root
[root@centos7 ~]# atq
1   Wed Dec 21 17:09:00 2022 a root
2   Wed Dec 21 17:10:00 2022 a root
3   Wed Dec 21 18:46:00 2022 a root

输出字段拆解:

  1. 数字 1/2/3:任务编号job id,删除、查看任务详情需要用到
  2. 日期时间:任务预定执行时间
  3. 字母a:任务队列名称,at一共26个队列a-z,字母越靠后优先级越低
  4. root:创建该任务的用户

(2)-q 指定任务队列

[root@centos7 ~]# at -q b now +5 minutes < myscript.sh
job 4 at Wed Dec 21 17:11:00 2022

参数解释:

  • -q b:指定该任务放入b队列,a队列优先级高于b队列,系统优先调度a队列任务
# 只查看b队列任务
[root@centos7 ~]# at -l -q b
4   Wed Dec 21 17:11:00 2022 b root
  • -q b:过滤只展示b队列任务

(3)at -c 查看任务完整内容

[root@centos7 ~]# at -c 3

参数解释:

  • -c:cat缩写,读取任务完整脚本内容
  • 3:要查看的任务ID号 输出内容解释:系统自动生成shell脚本,包含你写的所有执行命令,分隔符是系统自动生成,不用手动修改

(4)at -d / at -rm 删除等待中的定时任务

两条命令等价

[root@centos7 ~]# atrm 3
[root@centos7 ~]# atq
  • atrm:at remove,删除at任务,后面数字是任务ID
  • 执行后atq查询看不到3号任务,代表删除成功

4. at 用户权限控制 /etc/at.allow / /etc/at.deny

作用:限制哪些用户可以使用at定时任务,防止普通用户滥用定时任务占用服务器资源 匹配优先级规则(逐条看懂):

  1. 如果 /etc/at.allow 文件存在:只有写在这个文件内的用户才能使用at,其余全部禁止
  2. 如果 /etc/at.allow 不存在:读取 /etc/at.deny,文件内写的用户禁止使用at,其余所有人允许

查看系统默认配置:

[root@centos7 ~]# ls /etc/at.*
/etc/at.deny
[root@centos7 ~]# cat /etc/at.deny
# 内容为空

解读:系统没有at.allow,at.deny是空文件,所有用户都可以使用at命令

二、用户周期性计划任务 crontab(循环重复执行)

核心作用

at只能执行一次,crontab可以循环执行:每分钟、每小时、每天、每周、每月重复执行任务。 底层守护进程:crond,系统默认开机自启。 区分:用户级定时任务,每个普通用户独立拥有自己的定时任务,互不干扰。

1. crontab 全部子命令详解

crontab -l 查看当前用户定时任务

[jhl@centos7 ~]$ crontab -l
no crontab for jhl

参数解释:

  • -l:list缩写,列出当前登录用户全部定时任务
  • no crontab for jhl:用户jhl还没有创建任何定时任务

crontab -e 编辑当前用户定时任务

[jhl@centos7 ~]$ export EDITOR=vim
[jhl@centos7 ~]$ crontab -e

逐行解释:

  1. export EDITOR=vim
    
    • Linux默认crontab编辑器是vi,这条命令临时修改编辑器为vim,操作更友好
    • EDITOR:系统环境变量,定义文本编辑器程序
  2. -e:edit缩写,编辑当前用户定时任务文件

crontab任务单行标准格式(6段,必须全部看懂)

分 时 日 月 周 执行命令 字段顺序、取值范围、符号规则完整拆解:

字段含义取值范围特殊符号说明
第1段分钟0-59* 任意;x-y范围;x,y多值;*/x间隔
第2段小时0-23同上
第3段几号1-31同上
第4段月份1-12 / Jan-Feb同上
第5段星期0-7(0/7=周日,1周一)同上
第6段命令任意shell指令/脚本%代表换行,需要转义

特殊符号逐字解释:

  1. *:代表所有值,每分钟/每小时/每天都匹配
  2. x-y:连续范围,例如9-16 代表9、10、11、12、13、14、15、16
  3. x,y:离散多值,例如2,6 代表2点、6点
  4. */x:每隔x单位执行一次,*/2 每2分钟
定时任务示例逐行拆解

示例1:每年2月2日早上9点执行备份脚本

0 9 2 2 * /usr/local/bin/yearly_backup

分段解析: 0 → 第0分钟;9 → 9点;2 → 2号;2 → 2月;* → 星期无限制;执行备份脚本

示例2:7月每周五9点~16点,每5分钟执行输出

*/5 9-16 * Jul 5 echo "Chime"

分段解析: /5 每5分钟;9-16 9至16点; 任意日期;Jul 7月;5 周五;执行echo输出

示例3:周一至周五23点58分执行日报脚本

58 23 * * 1-5 /usr/local/bin/daily_report

分段解析: 58分;23点;任意日期;任意月份;1-5周一到周五;执行脚本

示例4:工作日早上9点发送邮件

0 9 * * 1-5 mutt -s "Checking in" [email protected] % Hi boss, just checking in.

特殊说明:% 在crontab中代表换行,不需要转义,后面内容作为邮件正文

实操案例
[jhl@centos7 ~]$ export EDITOR=vim
[jhl@centos7 ~]$ crontab -e
# 写入定时规则
*/2 2,6-23 * * * date >> /tmp/date.log
[jhl@centos7 ~]$ crontab -l
*/2 2,3-23 * * * date >> /tmp/date.log

规则拆解: */2 每2分钟;2,6-23 2点、6点至23点;每日每月任意星期;输出时间追加到日志

# 实时监控日志输出,验证定时任务是否运行
[jhl@centos7 ~]$ tail -f /tmp/date.log
  • tail:查看文件末尾内容;-f:实时跟踪文件新增内容

crontab -r 删除当前用户全部定时任务

[jhl@centos7 ~]$ crontab -r
[jhl@centos7 ~]$ crontab -l
no crontab for jhl

参数解释:

  • -r:remove,清空当前用户所有定时任务,不可恢复

crontab -u 管理员root操作其他用户定时任务

只有root用户有权限使用 -u 指定其他用户名

[root@centos7 ~]# crontab -u jhl -e
0 9 2 2 * /usr/local/bin/yearly_backup
0 9 * * 1-5 mutt -s "Checking in" [email protected] % Hi boss, just checking in.
[root@centos7 ~]# crontab -u jhl -r
[root@centos7 ~]# crontab -u jhl -l
no crontab for jhl

参数解释:

  • -u jhl:指定操作用户jhl,搭配-e编辑、-r删除、-l查看

crontab 文件名 从文件导入定时任务

[jhl@centos7 ~]$ vim mycron
# 文件内写入两条定时规则
0 9 2 2 * /usr/local/bin/yearly_backup
0 9 * * 1-5 mutt -s "Checking in" [email protected] % Hi boss, just checking in.
# 将文件内容覆盖当前用户所有定时任务
[jhl@centos7 ~]$ crontab mycron
[jhl@centos7 ~]$ crontab -l
0 9 2 2 * /usr/local/bin/yearly_backup
0 9 * * 1-5 mutt -s "Checking in" [email protected] % Hi boss, just checking in.

执行逻辑:读取mycron文件内所有定时规则,替换覆盖当前用户原有全部任务

2. 配套练习完整逐行注释

需求:

  1. 脚本 /usr/local/bin/myjob:后台计算md5、休眠20秒、杀死md5进程
  2. 定时规则:11月奇数日期,11点~18点,每2分钟执行一次

步骤1 创建脚本

[root@server ~ 11:16:02]# vim /usr/local/bin/myjob

脚本内容:

#!/bin/bash
md5sum /dev/zero &
sleep 20
pkill md5sum

逐行注释:

  1. #!/bin/bash:指定bash解释器运行脚本

  2. md5sum /dev/zero &
    
    • md5sum:计算文件md5哈希值
    • /dev/zero:系统无限零流文件
    • &:后台运行,不阻塞后续命令
  3. sleep 20:程序暂停20秒

  4. pkill md5sum:批量杀死所有md5sum后台进程

# 给脚本添加执行权限,否则定时任务无法运行
[root@server ~ 11:18:23]# chmod +x /usr/local/bin/myjob
  • chmod:修改文件权限;+x:增加执行权限

步骤2 配置定时任务

[root@server ~ 11:21:22]# crontab -e
# 写入规则
*/2 11-18 */2 11 * /usr/local/bin/myjob
[root@server ~ 11:22:35]# crontab -l
*/2 11-18 */2 11 * /usr/local/bin/myjob

规则分段拆解:

  1. */2:每2分钟执行一次
  2. 11-18:小时范围11点到18点
  3. */2:日期每隔2天 → 1、3、5、7…奇数号
  4. 11:仅11月份执行
  5. *:星期无限制
  6. /usr/local/bin/myjob:要执行的脚本完整路径

步骤3 监控任务运行

# 实时查看cron系统日志,观察任务调度记录
journalctl -f
# top命令查看md5sum进程是否自动启动、20秒后自动销毁
top

三、系统周期性计划任务(管理员全局任务,所有用户共用)

核心作用

用户crontab只能管理单个用户任务;系统级定时任务是root全局配置,可以指定任意用户执行,系统自带每日/每周/每月自动任务目录,适合服务器运维巡检、日志清理。 crond读取三处系统配置:

  1. /etc/crontab 全局主配置
  2. /etc/cron.d/ 自定义系统任务目录
  3. /etc/anacrontab 关机错过任务开机补执行

1. /etc/crontab 系统主定时文件

[root@centos7 ~]# cat /etc/crontab 
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar
# |  |  |  |  .---- day of week (0 - 6) 0=周日
# |  |  |  |  |
# *  *  *  *  * user-name  command

头部全局变量逐行解释

  1. SHELL=/bin/bash:定时任务使用bash解释器执行命令
  2. PATH:定时任务环境变量路径,定时任务默认PATH很短,命令尽量写全路径
  3. MAILTO=root:任务输出内容自动发送邮件给root用户

和用户crontab核心区别

用户crontab格式:分 时 日 月 周 命令 系统/etc/crontab格式:分 时 日 月 周 执行用户 命令 多一段【执行用户】,可以指定root、nginx、apache等任意用户运行任务

2. /etc/cron.d 自定义系统任务目录

作用:自定义系统定时任务推荐放在这里,系统更新不会覆盖文件

[root@centos7 ~]# ls /etc/cron.d
0hourly  raid-check  sysstat
[root@centos7 ~]# cat /etc/cron.d/0hourly 
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly

逐行解释: 01 * * * * root run-parts /etc/cron.hourly

  • 01:每小时第1分钟执行
      • *:每日每月任意星期
  • root:使用root用户执行
  • run-parts:工具,批量执行目录内所有可执行脚本
  • /etc/cron.hourly:每小时任务存放目录

配套系统内置定时目录:

  • /etc/cron.hourly 每小时执行脚本
  • /etc/cron.daily 每日执行脚本
  • /etc/cron.weekly 每周执行脚本
  • /etc/cron.monthly 每月执行脚本

3. /etc/anacrontab 补执行定时任务(关机补救)

作用:普通crontab服务器关机时错过的任务不会执行;anacron开机后自动补执行错过的每日/每周/每月任务,适合服务器经常关机场景。 CentOS7统一由crond进程管理,不需要单独启动anacron服务。

[root@centos7 ~]# cat /etc/anacrontab 
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
RANDOM_DELAY=45
START_HOURS_RANGE=3-22
#间隔天数 延迟分钟 任务标识 执行命令
1   5   cron.daily          nice run-parts /etc/cron.daily
7   25  cron.weekly         nice run-parts /etc/cron.weekly
@monthly 45 cron.monthly    nice run-parts /etc/cron.monthly

全局变量解释

  1. RANDOM_DELAY=45:任务启动随机延迟0~45分钟,避免多台服务器同一时间执行任务造成压力
  2. START_HOURS_RANGE=3-22:任务仅在凌晨3点~22点之间运行,深夜不执行

任务4字段完整拆解

  1. 间隔天数:1=每天,7=每周,@monthly每月
  2. 延迟分钟:开机后等待多久再执行任务(分散服务器IO压力)
  3. 任务标识:记录在/var/spool/anacron,标记上次执行时间,判断是否漏执行
  4. 执行命令:nice降低任务CPU优先级,run-parts批量执行目录脚本

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/2301_81987367/article/details/163313906

文章来源crawl

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--