Linux(CentOS)系统管理入门笔记(第十四期)------计划任务与进程调度管理:at/cron 与 nice/chrt
Linux系统管理入门系列更多文章欢迎访问:
Linux入门------系统管理1、Linux入门------系统管理2
我的主页:AOwhisky,这里有更多运维系统性知识整理和其他有趣内容,欢迎与我一起探讨学习~
引言:时间的艺术与资源的博弈------让系统"自动化"与"优先级"为你工作
作为系统管理员,你的工作中很大一部分是重复性的:每天凌晨备份数据库、每周清理日志文件、每月生成报表......如果这些都需要手动执行,不仅效率低下,还容易遗忘。解决这个问题的核心是计划任务------让系统在指定的时间自动执行预定的命令。
另一方面,当系统负载较高时,多个进程同时竞争 CPU 资源。哪些进程应该优先获得 CPU?哪些进程可以"排队等待"?这涉及进程调度------Linux 内核决定"下一个运行谁"的规则。
本期将把这两个主题放在一起,因为它们共同构成了 Linux 系统**"自动化"和"资源管理"**的两大支柱:
- 计划任务管理 :
at一次性任务、crontab周期性任务、系统级 cron 配置 - 进程调度管理 :
nice值调整优先级、renice动态调整、chrt实时调度策略
读完这一期,你将掌握如何让 Linux"准时自动工作",以及如何让关键任务"优先获得计算资源"。
--- Compiled and Authored by Whisky --- July 26 th, 2026
目录
- 一次性计划任务:at
- 1.1 atd 服务
- 1.2 at 命令基本用法
- 1.3 atq/at -l 查看任务队列
- 1.4 atrm 删除任务
- 1.5 at.allow 与 at.deny 访问控制
- 用户周期性计划任务:crontab
- 2.1 crond 服务
- 2.2 crontab 命令
- 2.3 Crontab 时间语法详解
- 2.4 实战示例
- 系统周期性计划任务
- 3.1 /etc/crontab
- 3.2 /etc/cron.d/
- 3.3 /etc/anacrontab
- 进程调度与优先级管理
- 4.1 进程调度器概述
- 4.2 实时调度器与 SCHED_RR/SCHED_FIFO
- 4.3 非实时调度器与 SCHED_NORMAL
- 4.4 nice 值:调整非实时进程优先级
- 4.5 renice:动态调整运行中进程的 nice 值
- 4.6 chrt:管理实时调度策略
- 总结与速查手册
1. 一次性计划任务:at
1.1 atd 服务
at 用于调度一次性的未来任务------即在某个指定的时间点执行一次命令。
at 不是一个单一命令,而是一套工具集:
- atd:后台守护进程,负责在指定时间执行任务
- at:提交任务的命令
- atq / at -l:查看任务队列
- atrm / at -d:删除待执行的任务
bash
# 安装 at(如果未安装)
[root@centos7 ~]# yum install -y at
# 确认 atd 服务运行中
[root@centos7 ~]# systemctl status atd
● atd.service - Job spooling tools
Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled)
Active: active (running) since ...
1.2 at 命令基本用法
语法 :at <时间规格>
at 从标准输入读取要执行的命令,按 Ctrl+D 结束输入。
bash
# 示例:5 分钟后执行命令
[root@centos7 ~]# at now +5 minutes
at> echo hello world > /tmp/hello.log
at> <EOT>
job 1 at Wed Dec 21 17:09:00 2022
从文件读取任务:
bash
# 创建脚本文件
[root@centos7 ~]# cat > myscript.sh << 'EOF'
#!/bin/bash
date >> /tmp/myscript.log
echo "Task executed" >> /tmp/myscript.log
EOF
# 使用 -f 选项从文件读取
[root@centos7 ~]# at now +5 minutes -f myscript.sh
job 2 at Wed Dec 21 17:10:00 2022
# 或使用重定向
[root@centos7 ~]# at now +100 minutes < myscript.sh
job 3 at Wed Dec 21 18:46:00 2022
时间规格格式:
| 格式 | 示例 | 说明 |
|---|---|---|
now + N minutes |
now + 5 minutes |
N 分钟后 |
now + N hours |
now + 2 hours |
N 小时后 |
now + N days |
now + 3 days |
N 天后 |
HH:MM |
15:30 |
今天的指定时间 |
HH:MM YYYY-MM-DD |
15:30 2026-12-31 |
指定日期时间 |
teatime |
teatime |
16:00 |
noon |
noon + 4 days |
12:00 |
am/pm |
2:00 pm |
下午 2 点 |
更多时间格式参考:
/usr/share/doc/at/timespec
1.3 查看任务队列
bash
# 查看当前所有等待执行的任务
[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
# 或使用 at -l
[root@centos7 ~]# at -l
1 Wed Dec 21 17:09:00 2022 a root
2 Wed Dec 21 17:10:00 2022 a root
# 查看特定任务详情
[root@centos7 ~]# at -c 3
# 显示任务 3 的环境变量和要执行的命令
...
#!/bin/bash
date >> /tmp/myscript.log
echo "Task executed" >> /tmp/myscript.log
1.4 删除任务
bash
# 删除任务(使用任务编号)
[root@centos7 ~]# atrm 3
[root@centos7 ~]# atq
1 Wed Dec 21 17:09:00 2022 a root
2 Wed Dec 21 17:10:00 2022 a root
# 或使用 at -d
[root@centos7 ~]# at -d 2
1.5 访问控制:/etc/at.allow 与 /etc/at.deny
at 的访问控制通过两个文件实现:
| 场景 | 规则 |
|---|---|
/etc/at.allow 存在 |
仅 该文件中列出的用户可以使用 at |
/etc/at.allow 不存在,/etc/at.deny 存在 |
除 该文件中列出的用户外,其他用户均可使用 at |
| 两个文件都不存在 | 仅 root 可以使用 at |
bash
# CentOS 7 默认配置
[root@centos7 ~]# cat /etc/at.deny
# 文件为空,表示允许所有用户使用 at
2. 用户周期性计划任务:crontab
2.1 crond 服务
周期性任务由 crond 守护进程管理,它每分钟检查一次是否有任务需要执行。
bash
[root@centos7 ~]# systemctl status crond
● crond.service - Command Scheduler
Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled)
Active: active (running) since ...
2.2 crontab 命令
crontab 命令用于管理用户的周期性任务。
| 命令 | 作用 |
|---|---|
crontab -l |
查看当前用户的周期性任务列表 |
crontab -e |
编辑周期性任务(默认使用 vi) |
crontab -r |
删除所有周期性任务 |
crontab -u username |
root 用户管理其他用户的周期性任务 |
bash
# 查看当前用户的周期性任务
[whisky@centos7 ~]$ crontab -l
no crontab for whisky
# 编辑任务(设置默认编辑器为 vim)
[whisky@centos7 ~]$ export EDITOR=vim
[whisky@centos7 ~]$ crontab -e
# 进入编辑界面后,每行一个任务
*/2 * * * * date >> /tmp/date.log
# 保存后查看
[whisky@centos7 ~]$ crontab -l
*/2 * * * * date >> /tmp/date.log
# 删除所有任务
[whisky@centos7 ~]$ crontab -r
[whisky@centos7 ~]$ crontab -l
no crontab for whisky
2.3 Crontab 时间语法详解
每个 cron 任务由 5 个时间字段 + 1 个命令 组成:
text
* * * * * command
┬ ┬ ┬ ┬ ┬
│ │ │ │ │
│ │ │ │ └─── 星期几(0-7,0 和 7 都表示周日)
│ │ │ └──────── 月份(1-12)
│ │ └───────────── 日期(1-31)
│ └────────────────── 小时(0-23)
└─────────────────────── 分钟(0-59)
特殊符号:
| 符号 | 含义 | 示例 |
|---|---|---|
* |
任意值(每) | * * * * * → 每分钟 |
, |
列表 | 1,15,30 * * * * → 第 1、15、30 分钟 |
- |
范围 | 9-17 * * * * → 9 点到 17 点之间 |
/ |
步长 | */5 * * * * → 每 5 分钟 |
@reboot |
系统启动时 | @reboot /script.sh |
2.4 实战示例
bash
# 示例 1:每年 2 月 2 日上午 9 点执行备份
0 9 2 2 * /usr/local/bin/yearly_backup
# 示例 2:7 月每周五上午 9 点到下午 4 点,每 5 分钟发一次提醒
*/5 9-16 * Jul 5 echo "Chime"
# 示例 3:每个工作日(周一至周五)23:58 执行日报
58 23 * * 1-5 /usr/local/bin/daily_report
# 示例 4:每周一上午 3 点清理日志
0 3 * * 1 find /var/log -name "*.log" -mtime +30 -delete
# 示例 5:每小时执行一次脚本(使用 @hourly 宏)
@hourly /usr/local/bin/hourly_task.sh
Crontab 中的环境变量:
bash
# 可以在 crontab 中定义环境变量
SHELL=/bin/bash
MAILTO=admin@example.com
PATH=/usr/local/bin:/usr/bin:/bin
# 任务会使用这些环境变量
0 2 * * * /usr/local/bin/backup.sh
2.5 使用文件编辑 crontab
除了 crontab -e,还可以从文件导入任务:
bash
[whisky@centos7 ~]$ cat > mycron << 'EOF'
0 9 2 2 * /usr/local/bin/yearly_backup
0 9 * * 1-5 mutt -s "Checking in" boss@example.com % Hi boss, just checking in.
EOF
# 从文件导入(会覆盖现有任务)
[whisky@centos7 ~]$ crontab mycron
[whisky@centos7 ~]$ crontab -l
0 9 2 2 * /usr/local/bin/yearly_backup
0 9 * * 1-5 mutt -s "Checking in" boss@example.com % Hi boss, just checking in.
💡 % 符号的特殊含义 :在 crontab 中,
%表示换行符,%后面的内容会作为命令的标准输入。
3. 系统周期性计划任务
除了用户级 crontab,系统级周期性任务通过配置文件定义。
3.1 /etc/crontab
/etc/crontab 是系统级的主配置文件,与用户 crontab 的区别是多了一个用户名字段:
bash
[root@centos7 ~]# cat /etc/crontab
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 的对比:
| 特征 | 用户 crontab | /etc/crontab |
|---|---|---|
| 用户字段 | ❌ 无(默认当前用户) | ✅ 需要指定 |
| 管理权限 | 普通用户可管理自己的 | 仅 root |
| 用途 | 个人定时任务 | 系统级任务 |
3.2 /etc/cron.d/
系统级定时任务应放在 /etc/cron.d/ 目录中,防止软件更新时覆盖 /etc/crontab。
bash
[root@centos7 ~]# ls /etc/cron.d/
0hourly raid-check sysstat
[root@centos7 ~]# cat /etc/cron.d/0hourly
# Run the hourly jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly
run-parts 是一个工具,它会按顺序执行指定目录中的所有可执行脚本。
3.3 /etc/anacrontab
/etc/anacrontab 用于管理延迟执行的系统任务,确保关键任务即使系统关机也会在下次启动后补执行。
bash
[root@centos7 ~]# cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
RANDOM_DELAY=45
START_HOURS_RANGE=3-22
#period in days delay in minutes job-identifier command
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
字段说明:
| 字段 | 含义 |
|---|---|
period in days |
执行间隔天数(1=每天,7=每周) |
delay in minutes |
启动前额外等待的分钟数 |
job-identifier |
唯一标识(用于记录上次执行时间) |
command |
要执行的命令 |
对应的脚本目录:
| 目录 | 用途 |
|---|---|
/etc/cron.hourly/ |
每小时执行(由 /etc/cron.d/0hourly 触发) |
/etc/cron.daily/ |
每天执行 |
/etc/cron.weekly/ |
每周执行 |
/etc/cron.monthly/ |
每月执行 |
4. 进程调度与优先级管理
4.1 进程调度器概述
Linux 系统中,进程/线程的数量通常远多于 CPU 核心数。进程调度器负责决定"下一个运行哪个进程"。
调度器分为两大类:
| 类型 | 调度策略 | 特点 | 优先级范围 |
|---|---|---|---|
| 实时调度器 | SCHED_RR、SCHED_FIFO |
高优先级,抢占式 | 1-99 |
| 非实时调度器 | SCHED_NORMAL(即 SCHED_OTHER) |
低优先级,公平分享 | -20 到 19(nice 值) |
SCHED_BATCH |
适合批量任务 | -20 到 19 | |
SCHED_IDLE |
极低优先级 | -20 到 19 |
关键结论 :实时调度器进程的优先级高于所有非实时调度器进程。
4.2 实时调度器
实时调度器管理的进程优先级范围为 1-99,数值越大优先级越高。
| 策略 | 含义 | 特点 |
|---|---|---|
SCHED_RR |
轮询调度 | 相同优先级的进程轮流获得 CPU 时间片 |
SCHED_FIFO |
先入先出 | 进程运行直到主动放弃或被更高优先级抢占 |
防止实时进程耗尽 CPU:
bash
# 查看实时调度限制参数
[root@centos7 ~]# sysctl kernel.sched_rt_runtime_us kernel.sched_rt_period_us
kernel.sched_rt_runtime_us = 950000
kernel.sched_rt_period_us = 1000000
# 解释:每 1 秒(1000000μs)中,实时进程最多使用 0.95 秒
# 剩余 0.05 秒留给非实时进程
4.3 非实时调度器
常规系统上大多数进程使用 SCHED_NORMAL(SCHED_OTHER)策略,通过 nice 值调整相对优先级。
nice 值范围:
| nice 值 | 优先级 | CPU 获取能力 |
|---|---|---|
| -20 | 最高 | 最强 |
| ... | ... | ... |
| 0 | 默认 | 普通 |
| ... | ... | ... |
| 19 | 最低 | 最弱 |
💡 白话理解:nice 值代表进程的"礼貌程度"。nice 值越高,进程越"客气"(把 CPU 让给其他进程);nice 值越低,进程越"霸道"(抢占更多 CPU)。
查看 nice 值:
bash
# 使用 top(NI 列)
[root@centos7 ~]# top -c
# 按 P 按 CPU 排序,NI 列显示 nice 值
# 使用 ps
[root@centos7 ~]# ps -o pid,ni,cmd -p $$
PID NI CMD
52751 0 -bash
4.4 nice:以指定 nice 值启动进程
bash
# 查看命令用法
[whisky@centos7 ~]$ nice --help
Usage: nice [OPTION] [COMMAND [ARG]...]
-n, --adjustment=N add integer N to the niceness (default 10)
实战示例:
bash
# 默认情况下,进程 nice 值为 0
[whisky@centos7 ~]$ md5sum /dev/zero &
[1] 55725
[whisky@centos7 ~]$ ps -o pid,ni,cmd 55725
PID NI CMD
55725 0 md5sum /dev/zero
# 以 nice 值 10 启动(普通用户可以使用正数)
[whisky@centos7 ~]$ nice -n 10 md5sum /dev/zero &
[2] 55742
[whisky@centos7 ~]$ ps -o pid,ni,cmd 55742
PID NI CMD
55742 10 md5sum /dev/zero
# 以 nice 值 -2 启动(普通用户无权限)
[whisky@centos7 ~]$ nice -n -2 md5sum /dev/zero &
nice: cannot set niceness: Permission denied
# 只有 root 可以设置负值(提高优先级)
4.5 renice:动态调整运行中的进程
bash
[whisky@centos7 ~]$ renice --help
Usage:
renice [-n] <priority> [-p|--pid] <pid>...
renice [-n] <priority> -u|--user <user>...
实战示例:
bash
# 查看当前进程 nice 值
[whisky@centos7 ~]$ ps -o pid,ni,cmd 55742
PID NI CMD
55742 10 md5sum /dev/zero
# 提高 nice 值(降低优先级),普通用户可以
[whisky@centos7 ~]$ renice -n 15 55742
55742 (process ID) old priority 10, new priority 15
# 降低 nice 值(提高优先级),普通用户无权限
[whisky@centos7 ~]$ renice -n 5 55742
renice: failed to set priority for 55742: Permission denied
# root 用户可以任意调整
[root@centos7 ~]# renice -n -2 55742
55742 old priority 15, new priority -2
用户权限规则:
| 操作 | 普通用户 | root |
|---|---|---|
| 提高 nice 值(降低优先级) | ✅ 可以 | ✅ 可以 |
| 降低 nice 值(提高优先级) | ❌ 不可以 | ✅ 可以 |
| 设置负 nice 值 | ❌ 不可以 | ✅ 可以 |
4.6 chrt:管理实时调度策略
chrt 命令用于查看和修改进程的实时调度策略。
bash
[root@centos7 ~]# chrt -m
SCHED_OTHER min/max priority : 0/0
SCHED_FIFO min/max priority : 1/99
SCHED_RR min/max priority : 1/99
SCHED_BATCH min/max priority : 0/0
SCHED_IDLE min/max priority : 0/0
使用实时调度启动进程:
bash
# 以 SCHED_RR 策略、优先级 5 运行 md5sum
[root@centos7 ~]# chrt -r 5 md5sum /dev/zero &
[1] 56225
# 查看进程的调度策略和优先级
[root@centos7 ~]# ps -o pid,cls,rtprio,cmd 56225
PID CLS RTPRIO CMD
56225 RR 5 md5sum /dev/zero
# CLS: RR = SCHED_RR, FF = SCHED_FIFO, TS = SCHED_OTHER
# RTPRIO: 实时优先级(空表示非实时)
修改已运行进程的调度策略:
bash
# 改为 SCHED_FIFO,优先级 10
[root@centos7 ~]# chrt -f --pid 10 56225
# 查看修改后的状态
[root@centos7 ~]# ps -o pid,cls,rtprio,cmd 56225
PID CLS RTPRIO CMD
56225 FF 10 md5sum /dev/zero
# 改回非实时(SCHED_OTHER)
[root@centos7 ~]# chrt -o --pid 0 56225
[root@centos7 ~]# ps -o pid,cls,rtprio,cmd 56225
PID CLS RTPRIO CMD
56225 TS - md5sum /dev/zero
5. 总结与速查手册
5.1 核心知识点一览
| 主题 | 关键点 |
|---|---|
| at 一次性任务 | at now + 5 minutes,atq 查看,atrm 删除 |
| crontab 周期性任务 | * * * * * command,分钟/小时/日期/月份/星期 |
| 系统级 cron | /etc/crontab、/etc/cron.d/、/etc/anacrontab |
| nice 值 | 范围 -20~19,值越高优先级越低 |
| renice | 动态调整运行中进程的 nice 值 |
| chrt | 管理实时调度策略(SCHED_RR/SCHED_FIFO) |
| 实时 vs 非实时 | 实时进程(1-99)优先级高于所有非实时进程 |
5.2 计划任务命令速查表
| 命令 | 作用 |
|---|---|
at now +5 minutes |
5 分钟后执行任务 |
atq 或 at -l |
查看等待执行的任务 |
atrm 编号 或 at -d 编号 |
删除任务 |
crontab -l |
查看周期性任务 |
crontab -e |
编辑周期性任务 |
crontab -r |
删除所有周期性任务 |
crontab -u username |
管理其他用户的周期性任务(仅 root) |
crontab file |
从文件导入周期性任务 |
5.3 进程调度命令速查表
| 命令 | 作用 |
|---|---|
nice -n 5 command |
以 nice 值 5 启动命令 |
renice -n 10 -p PID |
将进程 nice 值改为 10 |
chrt -r 5 command |
以 SCHED_RR 优先级 5 启动 |
chrt -f --pid 10 PID |
将进程改为 SCHED_FIFO 优先级 10 |
chrt -o --pid 0 PID |
将进程改为 SCHED_OTHER(非实时) |
ps -o pid,cls,rtprio,cmd |
查看进程调度策略和优先级 |
5.4 Crontab 时间字段速查
| 位置 | 字段 | 范围 |
|---|---|---|
| 1 | 分钟 | 0-59 |
| 2 | 小时 | 0-23 |
| 3 | 日期 | 1-31 |
| 4 | 月份 | 1-12(或 Jan-Dec) |
| 5 | 星期 | 0-7(0 和 7 都表示周日,或 Sun-Sat) |
5.5 系统 cron 目录对比
| 目录/文件 | 用途 | 管理方式 |
|---|---|---|
crontab -e |
用户个人任务 | 用户自己 |
/etc/crontab |
系统级任务 | root 手动编辑 |
/etc/cron.d/ |
系统级任务(独立文件) | root 创建 .conf 文件 |
/etc/cron.hourly/ |
每小时执行 | 放可执行脚本 |
/etc/cron.daily/ |
每天执行 | 放可执行脚本 |
/etc/cron.weekly/ |
每周执行 | 放可执行脚本 |
/etc/cron.monthly/ |
每月执行 | 放可执行脚本 |
5.6 常见错误排查
| 错误 | 原因 | 解决方案 |
|---|---|---|
at: command not found |
at 未安装 | yum install -y at |
You do not have permission |
用户在 at.deny 中 | 管理员修改 at.deny 或添加 at.allow |
| Crontab 任务未执行 | 命令路径问题 | 使用绝对路径 (如 /usr/bin/date) |
| Crontab 任务未执行 | 脚本无执行权限 | chmod +x script.sh |
nice: Permission denied |
普通用户设置负值 | 使用 root 权限 |
chrt: failed to set pid |
权限不足 | 需要 root 权限 |
| 实时进程占满 CPU | 实时调度器限制 | 检查 kernel.sched_rt_runtime_us |
5.7 思考与拓展(原课后作业转化)
at和crontab的区别是什么?
→at用于执行一次性 任务;crontab用于执行周期性任务。/etc/crontab和用户crontab的格式区别是什么?
→/etc/crontab有 6 个字段(多一个用户名 字段),用户crontab只有 5 个时间字段 + 命令。nice值和chrt管理的优先级有什么关系?
→nice值(-20~19)仅影响非实时调度器(SCHED_OTHER)的优先级;chrt管理的实时优先级(1-99)高于所有非实时进程。- 为什么普通用户只能"升高"nice 值(降低优先级),不能"降低"nice 值(提高优先级)?
→ 防止普通用户抢占系统资源,影响其他用户和系统稳定性。 SCHED_RR和SCHED_FIFO的区别是什么?
→SCHED_RR:相同优先级的进程轮流获取 CPU 时间片(轮询);SCHED_FIFO:进程按先入先出顺序执行,直到主动放弃。
5.8 生产环境最佳实践
| 场景 | 建议 |
|---|---|
| 数据库备份 | 使用 crontab 安排在凌晨低峰期(如 0 3 * * *) |
| 日志轮转 | 使用系统自带的 logrotate,配合 cron 执行 |
| 长期运行任务 | 使用 at 安排在特定时间执行,避免 cron 重复触发 |
| 关键进程优先级 | 使用 nice -n -5 提高数据库进程优先级 |
| 禁止实时调度滥用 | 监控 `ps -eo cls,pid,cmd |
| crontab 调试 | 在 cron 命令中重定向日志:0 2 * * * /script.sh >> /var/log/script.log 2>&1 |
下期预告 :计划任务和进程调度让系统"按时工作"和"合理分配资源",但这一切都建立在存储系统 之上。下一期我们将进入 文件系统与存储管理 系列------从识别块设备开始,学习文件系统的挂载与卸载、磁盘空间查看,以及 locate 和 find 命令的高效文件查找技巧。敬请期待第十五期!
--- Compiled and Authored by Whisky --- July 26 th, 2026