Skip to content
Kurisu
Go back

Linux 计划任务

Linux 计划任务分两类:一次性的 at 与周期性的 cron。


一、延迟用户作业 — at

1.1 at 简介

at 用于在将来某个时间点运行一个或一组命令(延迟任务);at 软件包提供 atd 守护进程与命令行工具,默认自动安装并启用。

# 查看 atd 进程
ps -ef | grep atd

# 查看 atd 服务状态
systemctl status atd.service

atd 提供 a 到 z 共 26 个队列,作业按字母排列,队列越靠后优先级越低。

1.2 相关命令与文件

命令/文件说明
at计划新作业
atq查看待处理队列
atrm删除计划的作业
batch负载允许时运行作业
/etc/at.allow白名单(允许的用户)
/etc/at.deny黑名单(禁止的用户)
/var/spool/at/作业存储目录

1.3 TIMESPEC 时间格式

at 接受灵活时间表达式:

# 从现在起 5 分钟后
at now +5min

# 今天下午茶时间 (16:00)
at teatime

# 4 天后的中午
at noon +4 days

# 指定日期和时间
at 5pm august 3 2023

# 明天下午 4 点
at teatime tomorrow

# 2 小时后
at now +2 hours

1.4 at 命令使用示例

# 计划一个延迟任务
at 5pm august 3 2023
warning: commands will be executed using /bin/sh
at> wall hello
at> <EOT>                    # 按 Ctrl+D 结束输入
job 1 at Thu Aug  3 17:00:00 2023

# 从文件读取命令(适合复杂命令)
at now +1 hour < /path/to/script.sh

1.5 管理延迟作业

# 查看待处理作业
atq
# 输出示例:
# 1   Thu Aug  3 17:00:00 2023 a root
# 2   Sun Mar 12 12:00:00 2023 a root

# 输出各字段说明:
# 第一个字段:唯一作业编号
# 第二个字段:计划执行日期和时间
# 第三个字段:作业队列(默认 a)
# 第四个字段:作业所有者

# 查看作业的具体命令
at -c 1

# 删除作业
atrm 2

# 验证删除
atq

普通用户只能管自己的作业,root 可管所有用户。

1.6 用户权限控制

条件结果
在 /etc/at.allow 中允许使用 at
在 /etc/at.deny 中禁止使用 at
用户同时在两个文件中允许使用 at
两个文件都不存在只有 root 能使用 at
文件存在但为空所有用户均可使用
# 禁止 redhat 用户使用 at
echo redhat >> /etc/at.deny

# 允许 redhat 用户使用 at
echo redhat >> /etc/at.allow

二、周期性用户作业 — crond

2.1 crond 简介

周期性作业由 cronie 软件包提供的 crond 守护进程执行,默认启用。

# 查看 crond 进程
ps -ef | grep crond

# 查看 crond 服务状态
systemctl status crond.service

输出/错误未重定向时,crond 会邮件通知作业所有者。

2.2 crontab 命令

命令用途
crontab -l列出当前用户作业
crontab -e编辑当前用户的作业
crontab -r删除当前用户的所有作业
crontab filename从文件导入(替换现有)
crontab -u username -eroot 编辑指定用户作业
# 普通用户管理自己的任务
crontab -e    # 编辑
crontab -l    # 查看
crontab -r    # 删除所有

# root 管理其他用户的任务
crontab -u redhat -e
crontab -u redhat -l

2.3 crontab 时间格式

crontab 字段顺序:

分钟  小时  几号  月  星期几  命令
 0-59  0-23  1-31 1-12 0-7

语法规则:

符号说明示例
*任意值,始终匹配* * * * * (每分钟)
数字精确值0 5 * * * (每天5:00)
x-y范围9-17 (9点到17点)
x,y列表1,3,5 (第1,3,5)
*/x间隔*/5 (每5分钟/小时)

月份和星期可用三字母缩写:

类型缩写
月份Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
星期Sun, Mon, Tue, Wed, Thu, Fri, Sat (0=Sun, 7=Sun)

2.4 crontab 示例

# 每年 2 月 2 日上午 9 点执行一次年度备份
0 9 2 2 * /usr/local/bin/yearly_backup

# 七月每周五上午 9 点到下午 5 点之间,每 5 分钟发送 Chime 邮件
*/5 9-16 * Jul 5 echo "Chime"

# 每个工作日午夜前两分钟运行日报脚本
58 23 * * 1-5 /usr/local/bin/daily_report

# 每个工作日上午 9 点发送检查邮件
0 9 * * 1-5 mutt -s "Checking in" boss@example.com % Hi there boss, just checking in.

# 每两分钟记录一次当前时间
*/2 * * * * date >> /tmp/mylog.txt

# 凌晨 2 点执行系统清理(输出重定向)
0 2 * * * /usr/local/bin/cleanup.sh > /dev/null 2>&1

百分比符号 % 会被当作换行字符,其后的内容通过 stdin 传给命令。

2.5 用户权限控制

权限控制文件与规则同 at:

文件作用
/etc/cron.allow白名单(允许的用户)
/etc/cron.deny黑名单(禁止的用户)

同时存在时 allow 优先;两个文件都不存在时只有 root 能使用。

# 拒绝 redhat 用户使用 crontab
echo redhat >> /etc/cron.deny

# 删除控制文件(仅 root 可用)
rm -rf /etc/cron.allow /etc/cron.deny

2.6 日志查看

# 查看 Cron 执行日志
tail -f /var/log/cron

三、周期性系统作业

3.1 系统 crontab 文件

系统作业应写系统级 crontab 文件;格式同用户 crontab,只是命令前多一个用户字段。

# /etc/crontab 示例格式
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,apr ...
# |  |  |  |  .---- day of week (0 - 6)
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed

3.2 周期性系统作业的位置

位置用途
/etc/crontab默认系统 crontab(可能被包更新覆盖)
/etc/cron.d/自定义 crontab 文件(推荐使用)
/etc/cron.hourly/每小时执行
/etc/cron.daily/每天执行
/etc/cron.weekly/每周执行
/etc/cron.monthly/每月执行

自定义任务放 /etc/cron.d/,避免包更新覆盖 /etc/crontab。

# 创建系统级定时任务
cat > /etc/cron.d/custom-task << 'EOF'
# 每天凌晨 3 点以 root 身份运行备份
0 3 * * * root /usr/local/bin/backup.sh
EOF

3.3 目录脚本要求

/etc/cron.hourly/、/etc/cron.daily/ 等目录中的脚本必须是可执行文件:

# 创建每日任务脚本
cat > /etc/cron.daily/user-count.sh << 'EOF'
#!/bin/bash
USERCOUNT=$(w -h | wc -l)
logger "There are currently ${USERCOUNT} active users"
EOF

chmod +x /etc/cron.daily/user-count.sh

四、anacron — 补救执行

4.1 anacron 简介

anacron 保证作业不会因系统关机/休眠被跳过——错过时间的每日作业会在系统就绪后补跑。

/var/spool/anacron/ 为每个作业保存时间戳,用于确定上次运行时间。

4.2 /etc/anacrontab 语法

每行四个字段:

以天为单位的间隔  延迟(分钟)  作业标识符  命令
# /etc/anacrontab 示例
# 环境变量
START_HOURS_RANGE=3-22

# 每日作业 (间隔1天,延迟5分钟运行)
1       5       cron.daily      run-parts /etc/cron.daily

# 每周作业 (间隔7天,延迟25分钟运行)
7       25      cron.weekly     run-parts /etc/cron.weekly

# 每月作业 (间隔30天,延迟45分钟运行)
@monthly 45     cron.monthly    run-parts /etc/cron.monthly
字段说明
间隔天数整数或宏 @daily(1)、@weekly(7)、@monthly(30)
延迟(分钟)crond 启动后等待的时间
作业号日志中标识作业的唯一名称
命令要执行的命令

START_HOURS_RANGE 限制作业可运行的时间范围,超出则作业不启动。


五、at 与 cron 对比

特性atcron
执行方式一次性延迟执行周期性重复执行
守护进程atdcrond
队列数a-z 共 26 个无队列概念
作业存储/var/spool/at//var/spool/cron/
配置命令at, atq, atrmcrontab -e/-l/-r
权限控制/etc/at.allow, /etc/at.deny/etc/cron.allow, /etc/cron.deny
适用场景临时性、一次性任务定期维护、监控、备份

六、最佳实践

  1. 命令用绝对路径;2. 输出重定向到日志,避免堆邮件;3. 开头设 SHELL=/bin/bash
  2. 系统任务放 /etc/cron.d/;5. 目录脚本加可执行权限;6. 用 crontab -l 验语法、/var/log/cron 确认执行

Share this post:

Previous Post
Firewalld 防火墙
Next Post
Chronyd 时间同步