CentOS Stream 9 进程管理 ---语法详解与实战案例
一、Linux进程概述
1.1 进程的概念
进程(Process):是正在运行的程序实例,是系统资源分配和调度的基本单位。
每个进程拥有:
- 唯一的进程ID(PID)
- 内存空间(堆、栈、数据段、代码段)
- 打开的文件描述符
- 执行状态(运行、睡眠、僵尸等)
- 用户和组权限
✅ 查看当前 shell 的 PID:
bash
echo $$
# 输出:31245(示例)
1.2 程序和进程
| 项目 | 说明 |
|---|---|
| 程序 | 存储在磁盘上的可执行文件(静态) |
| 进程 | 程序被加载到内存中运行的实例(动态) |
✅ 示例:
bash
# /bin/ls 是程序
# 执行 ls -l 时,系统创建一个进程来运行它
ls -l &
echo $! # 查看刚启动的后台进程 PID
1.3 进程的状态(5种主要状态)
| 状态码 | 状态名 | 说明 |
|---|---|---|
| R | Running | 正在运行或在运行队列中等待 CPU |
| S | Sleep | 可中断睡眠(等待事件,如 I/O) |
| D | Disk Sleep | 不可中断睡眠(通常等待磁盘 I/O,不能被 kill) |
| Z | Zombie | 僵尸进程(子进程结束,父进程未回收) |
| T | Stopped | 暂停(被信号如 SIGSTOP 或 Ctrl+Z 挂起) |
✅ 查看进程状态:
bash
ps aux | grep sleep
# 输出示例:alice 12345 S 0.0 0.1 0:00 sleep 100
1.4 进程的分类
| 类型 | 说明 |
|---|---|
| 前台进程 | 与终端交互,阻塞终端输入(默认) |
| 后台进程 | 不阻塞终端,以 & 启动 |
| 守护进程 | 无终端控制,系统服务(如 sshd, nginx) |
| 子进程 | 由父进程 fork 创建 |
| 僵尸进程 | 已结束但未被父进程 wait() 回收 |
✅ 查看守护进程:
bash
ps -ef | grep nginx
# 通常 PPID=1(systemd)
1.5 进程优先级(Nice 值)
| Nice 值范围 | 说明 |
|---|---|
| -20 ~ 19 | 数值越小,优先级越高 |
| 默认值 | 0 |
| root 可设负值 | 普通用户只能设 0~19 |
✅ 查看进程优先级:
bash
ps -l
# 输出中的 NI 列即为 nice 值
二、进程状态监测
2.1 静态监测:ps 命令
功能:快照式查看当前进程状态
常用选项组合:
| 选项 | 说明 |
|---|---|
ps aux |
BSD 风格,显示所有用户进程 |
ps -ef |
POSIX 风格,显示完整格式 |
ps -l |
显示当前 shell 的进程详细信息 |
ps -u 用户名 |
显示指定用户的进程 |
✅ 案例:查看所有进程并过滤 nginx
bash
ps aux | grep nginx
✅ 案例:查看进程树结构(带 PPID)
bash
ps -ef --forest | grep nginx
✅ 案例:自定义输出列(PID, USER, NI, CMD)
bash
ps -eo pid,user,ni,cmd | head -5
# 输出:
# PID USER NI CMD
# 1 root 0 /usr/lib/systemd/systemd --switched-root
# 2 root 0 [kthreadd]
2.2 动态监测:top 命令
功能:实时动态显示进程资源占用(CPU、内存等)
交互命令(在 top 界面中输入):
| 键 | 功能 |
|---|---|
P |
按 CPU 使用率排序 |
M |
按内存使用率排序 |
k |
杀死进程(需输入 PID) |
r |
调整进程 nice 值 |
q |
退出 top |
h |
显示帮助 |
✅ 启动 top:
bash
top
✅ 案例:只监控指定用户进程
bash
top -u alice
✅ 案例:批量模式(用于脚本)
bash
top -b -n 1 > /tmp/top_snapshot.txt
# -b: batch mode, -n: 迭代次数
2.3 查看进程树:pstree
功能:以树状图显示进程父子关系
常用选项:
| 选项 | 说明 |
|---|---|
pstree |
显示当前用户进程树 |
pstree -p |
显示 PID |
pstree -u |
显示用户切换 |
pstree -s PID |
显示指定进程的祖先树 |
✅ 案例:查看 sshd 进程树
bash
pstree -p | grep sshd
# 输出:sshd(1234)─┬─sshd(5678)───bash(5679)
# └─sshd(8765)───bash(8766)
✅ 案例:查看指定进程的完整祖先
bash
pstree -s 5679
# 显示从 systemd 到 bash(5679) 的完整路径
2.4 列出进程打开文件:lsof
功能:List Open Files ------ 查看进程打开的文件、端口、设备等
常用用法:
| 用法 | 说明 |
|---|---|
lsof -p PID |
查看指定进程打开的文件 |
lsof /path/to/file |
查看谁在使用某个文件 |
lsof -i :80 |
查看占用 80 端口的进程 |
lsof -u username |
查看某用户打开的文件 |
lsof +D /dir |
查看目录下被打开的文件 |
✅ 案例:查看 nginx 打开了哪些文件
bash
pgrep nginx | xargs lsof -p
# 或
lsof -c nginx
✅ 案例:查看谁在占用 22 端口
bash
lsof -i :22
# 输出:sshd 1234 root 3u IPv4 0x... TCP *:ssh (LISTEN)
✅ 案例:查看用户 alice 打开的文件
bash
lsof -u alice
三、进程状态控制
3.1 调整进程优先级:nice
功能:启动进程时设置 nice 值
语法:
bash
nice -n 优先级值 命令 [参数...]
✅ 案例:以低优先级运行压缩任务(减少对系统影响)
bash
nice -n 10 tar -czf backup.tar.gz /home/alice &
# 普通用户只能设 0~19,root 可设负值
✅ 案例:root 以高优先级运行关键任务
bash
sudo nice -n -5 /opt/critical_app --start
📝 说明:
- 不指定
-n默认为 10 nice 命令仅影响新启动的进程
3.2 改变运行中进程优先级:renice
功能:动态调整正在运行的进程的 nice 值
语法:
bash
renice 优先级值 -p PID
renice 优先级值 -u 用户名
✅ 案例:降低某进程优先级
bash
# 先查 PID
ps aux | grep compress_job
# 假设 PID=5678
renice 15 -p 5678
# 输出:5678 (process ID) old priority 10, new priority 15
✅ 案例:调整用户所有进程优先级
bash
renice 10 -u alice
⚠️ 权限限制:
- 普通用户只能提高 nice 值(降低优先级)
- 降低 nice 值(提高优先级)需 root 权限
3.3 向进程发送信号:kill
功能:发送信号给进程,默认 SIGTERM(15)
常用信号:
| 信号 | 编号 | 说明 |
|---|---|---|
| SIGTERM | 15 | 终止(默认,可被捕获) |
| SIGKILL | 9 | 强制终止(不可捕获) |
| SIGSTOP | 19 | 暂停进程 |
| SIGCONT | 18 | 继续暂停的进程 |
| SIGHUP | 1 | 重新加载配置(如 nginx) |
✅ 查看所有信号:
bash
kill -l
✅ 案例:优雅终止进程
bash
kill 1234 # 发送 SIGTERM(15)
kill -15 1234 # 同上
✅ 案例:强制杀死无响应进程
bash
kill -9 1234 # SIGKILL,立即终止
✅ 案例:暂停和恢复进程
bash
kill -STOP 1234 # 暂停进程
kill -CONT 1234 # 恢复进程
3.4 通过名称"杀死"进程:killall
功能:按进程名批量发送信号
语法:
bash
killall [信号] 进程名
✅ 案例:终止所有 firefox 进程
bash
killall firefox
✅ 案例:强制终止所有 python 脚本
bash
killall -9 python3
✅ 案例:重新加载 nginx 配置
bash
killall -HUP nginx
# 等价于:sudo systemctl reload nginx
⚠️ 警告:
killall会杀死所有匹配名称的进程- 在生产环境慎用,建议先用
pgrep确认
四、进程启动与作业控制
4.1 进程的启动
➤ 前台启动(默认)
bash
sleep 60
# 阻塞终端,直到结束
➤ 后台启动(加 &)
bash
sleep 60 &
# 立即返回提示符,进程在后台运行
# 输出:[1] 12345
4.2 进程的挂起
方法 :在前台运行时按 Ctrl + Z
✅ 案例:
bash
ping google.com
# 按 Ctrl+Z
# 输出:[1]+ Stopped ping google.com
4.3 使用 jobs 命令显示任务状态
功能:查看当前 shell 的作业(jobs)
输出格式:
[作业号] 状态 命令
✅ 案例:
bash
jobs
# 输出:
# [1]+ Stopped ping google.com
# [2]- Running sleep 100 &
✅ 选项:
jobs -l:显示 PIDjobs -r:只显示运行中的jobs -s:只显示停止的
4.4 使用 fg 命令将任务移至前台
语法:
bash
fg %作业号
fg %1 # 将作业1移到前台
fg # 默认操作最近一个作业(+号标记)
✅ 案例:
bash
fg %1
# 继续执行被暂停的 ping 命令,且占用终端
4.5 使用 bg 命令移动任务至后台
语法:
bash
bg %作业号
bg %1 # 将暂停的作业1转为后台运行
bg # 默认操作最近一个暂停作业
✅ 案例:
bash
bg %1
# 输出:[1]+ ping google.com &
# 进程在后台继续运行
📝 说明:
bg只能用于已暂停的作业- 运行中的后台作业无需
bg
五、综合案例:使用 ping 命令演示进程管理
🎯 案例概述
通过 ping 命令演示:
- 启动进程
- 挂起进程
- 查看作业状态
- 前后台切换
- 终止进程
🧩 案例详解(带详细注释)
bash
#!/bin/bash
# 文件名:ping_process_demo.sh
# 功能:完整演示进程管理操作
echo "🚀 开始 ping 进程管理演示..."
echo "=================================="
# === 1. 启动 ping 到前台 ===
echo "🔧 步骤1:启动 ping 到前台(按 Ctrl+C 可终止,但我们用 Ctrl+Z)"
echo " 执行:ping -c 10 google.com"
ping -c 10 google.com
# 实际操作中,你应手动按 Ctrl+Z 挂起
# 为自动化演示,我们改用后台启动再挂起
echo "⚠️ 为脚本自动化,我们改用后台启动再挂起方式演示"
# === 2. 启动到后台 ===
ping -c 60 google.com > /tmp/ping.log 2>&1 &
PING_PID=$!
echo "✅ 已启动 ping 后台进程,PID=$PING_PID"
# === 3. 暂停进程 ===
echo "⏸️ 步骤2:暂停进程(发送 SIGSTOP)"
kill -STOP $PING_PID
sleep 2
# === 4. 查看作业状态 ===
echo "📋 步骤3:使用 jobs 查看作业状态"
jobs -l
# === 5. 移到前台 ===
echo "🖥️ 步骤4:使用 fg 移到前台(脚本中我们再挂起)"
# fg %1 # 交互式命令,脚本中不适用
# 改为:继续后再次暂停
kill -CONT $PING_PID
sleep 2
kill -STOP $PING_PID
echo "✅ 已演示 fg 概念(实际需交互操作)"
# === 6. 移到后台运行 ===
echo "🌀 步骤5:使用 bg 让暂停的进程在后台继续运行"
kill -CONT $PING_PID # bg 的本质是发送 SIGCONT
echo "✅ 进程已在后台继续运行"
# === 7. 查看进程状态 ===
echo "🔍 步骤6:使用 ps 查看进程状态"
ps -p $PING_PID -o pid,ppid,stat,cmd
# === 8. 调整优先级 ===
echo "🎚️ 步骤7:使用 renice 降低优先级"
renice 10 -p $PING_PID
# === 9. 终止进程 ===
echo "⏹️ 步骤8:使用 kill 终止进程"
kill $PING_PID
wait $PING_PID 2>/dev/null && echo "✅ 进程已优雅终止"
# 验证是否终止
if ! ps -p $PING_PID > /dev/null; then
echo "✅ 进程 $PING_PID 已不存在"
fi
echo "🎉 演示完成!"
echo "=================================="
💡 使用方法:
bash
chmod +x ping_process_demo.sh
./ping_process_demo.sh
📝 说明:
- 实际教学中,建议手动操作
Ctrl+Z、fg、bg - 脚本中用
kill -STOP/CONT模拟挂起/恢复
六、综合案例:演示如何将进程移动到后台并脱离终端运行
🎯 案例概述
场景 :
启动一个长时间运行的任务(如 rsync 备份),需:
- 从终端启动
- 挂起后放入后台
- 使其脱离终端(即使关闭 SSH 也不终止)
- 验证其父进程变为 systemd(PID=1)
✅ 核心命令:
nohup+&或disown
🧩 案例详解(两种方法)
✅ 方法一:使用 nohup(推荐)
bash
#!/bin/bash
# 文件名:detach_process_nohup.sh
echo "🚀 方法一:使用 nohup 脱离终端"
echo "=================================="
# 启动长时间任务(模拟备份)
nohup sleep 3600 > /tmp/backup.log 2>&1 &
BACKUP_PID=$!
echo "✅ 任务已启动,PID=$BACKUP_PID"
echo "📄 日志将输出到 /tmp/backup.log"
echo " 即使关闭终端,进程也会继续运行"
# 查看进程及其父进程
sleep 2
ps -p $BACKUP_PID -o pid,ppid,cmd
# 预期输出:
# PID PPID CMD
# 12345 1 sleep 3600 ← PPID=1 表示已脱离原终端
echo "✅ 进程已成功脱离终端控制!"
echo "🛑 如需终止:kill $BACKUP_PID"
echo "=================================="
✅ 方法二:使用 disown(适合已启动进程)
bash
#!/bin/bash
# 文件名:detach_process_disown.sh
echo "🚀 方法二:使用 disown 脱离终端"
echo "=================================="
# 1. 启动进程到后台
sleep 3600 > /tmp/backup2.log 2>&1 &
DISOWN_PID=$!
echo "✅ 后台进程已启动,PID=$DISOWN_PID"
# 2. 从作业表中移除(脱离当前 shell)
disown %%
echo "✅ 已使用 disown 脱离作业控制"
echo " 关闭终端后进程仍会运行"
# 3. 验证父进程
sleep 2
ps -p $DISOWN_PID -o pid,ppid,stat,cmd
# 4. 查看是否还在 jobs 中
echo "📋 当前作业列表:"
jobs
# 应无输出(已被 disown)
echo "✅ 进程已脱离终端!"
echo "🛑 如需终止:kill $DISOWN_PID"
echo "=================================="
✅ 方法三:终极方案 ------ screen 或 tmux(生产推荐)
虽不在原章节,但强烈推荐用于生产环境!
bash
# 安装 screen
sudo dnf install screen -y
# 创建新会话
screen -S backup_session
# 在 screen 中执行命令
rsync -av /source/ /backup/
# 按 Ctrl+A, 再按 D → 脱离会话
# 重新连接:screen -r backup_session
# 查看所有会话:screen -ls
✅ 学习建议与最佳实践
- 优先使用
systemd service:长期运行的服务应创建 systemd unit 文件,而非手动后台运行。 - 日志重定向:后台进程务必重定向 stdout/stderr,避免终端关闭后进程因写终端失败而异常。
- 使用
nohup或disown:确保进程不随终端退出而终止。 - 避免滥用
kill -9:优先使用SIGTERM(15)让程序优雅退出。 - 监控僵尸进程 :定期检查
ps aux | grep 'Z',长期存在需修复父进程。 - 合理设置优先级:避免负 nice 值占用过多 CPU,影响系统稳定性。
- 作业控制仅限当前 shell :
fg/bg/jobs只对当前终端会话有效。
📚 附录:进程管理命令速查表
| 功能 | 命令示例 |
|---|---|
| 查看进程 | ps aux, top, htop |
| 查看进程树 | pstree -p |
| 查看打开文件 | lsof -p PID, lsof -i :80 |
| 启动时设优先级 | nice -n 10 command & |
| 修改运行中优先级 | renice 15 -p PID |
| 发送信号 | kill -15 PID, kill -9 PID |
| 按名称杀进程 | killall firefox |
| 挂起进程 | Ctrl+Z 或 kill -STOP PID |
| 恢复进程 | fg / bg 或 kill -CONT PID |
| 查看作业 | jobs, jobs -l |
| 脱离终端运行 | nohup cmd & 或 cmd & + disown |
| 查看信号列表 | kill -l |
这份文档覆盖了 CentOS Stream 9 进程管理的全部核心知识点 + 语法细节 + 实用案例 + 综合项目,所有代码均含详细注释,可直接用于教学、自学或生产环境参考。