第55课:后台前台与作业控制
学习目标
- 理解前台、后台进程的概念及其在终端中的作用
- 掌握使用
jobs、fg、bg命令查看和管理作业 - 学会使用
Ctrl+Z、Ctrl+C等快捷键控制进程 - 理解并处理后台进程与终端控制(TTY)的关系
核心概念
1. 前台与后台进程
- 前台进程:当前在终端窗口中运行,接收用户输入(如键盘按键)并直接影响终端显示的进程。一个终端会话通常同一时间只有一个前台进程。
- 后台进程:在后台运行,不占用终端的输入和输出。用户可以在执行后台命令的同时继续使用终端。
- 比喻:把终端窗口想象成一个舞台。前台进程是正在舞台上表演的演员(聚光灯下),而后台进程则是在后台准备、但不在舞台上的演员。
2. 作业(Job)与作业控制
- 当你在Shell(如bash)中启动一个进程时,Shell会为其分配一个作业号(Job ID)。这是Shell内部管理的标识。
- 作业控制(Job Control)允许你:
- 暂停正在运行的进程
- 在前台和后台之间切换进程
- 查看当前有哪些进程在后台或已暂停
3. 常用控制信号与快捷键
Ctrl+C:向当前前台进程发送SIGINT信号,通常用于终止进程。Ctrl+Z:向当前前台进程发送SIGTSTP信号,将其挂起(暂停)。进程状态变为Stopped。- 命令行末尾加
&:将命令直接放入后台运行。例如sleep 60 &。
代码示例
# 场景:演示作业控制的典型工作流程
# 1. 启动一个前台任务,并立即挂起它
sleep 300
# 按下 Ctrl+Z
# 终端会显示:[1]+ Stopped sleep 300
# 说明:作业号[1]的 `sleep 300` 进程已被挂起。
# 2. 查看当前的所有作业
jobs
# 输出示例:
# [1]+ Stopped sleep 300
# [2]- Running find / -name “*.log” &
# (+ 表示默认作业,- 表示上一个作业)
# 3. 将挂起的作业放到后台继续运行
bg %1 # 或简写为 bg %1, %1 是作业号
# 输出:[1]+ sleep 300 &
# 说明:作业[1]现在已在后台运行。
# 4. 再次查看作业状态,确认它已在后台运行
jobs
# [1]+ Running sleep 300 &
# 5. 将后台作业调回前台运行
fg %1
# 说明:sleep 300 又回到前台。你可以再次用 Ctrl+Z 挂起,或用 Ctrl+C 终止。
# 6. 终止一个后台作业
# 首先,用 jobs 找到作业号,例如作业号为 2 的 find 命令
kill %2 # 通过作业号发送 SIGTERM 信号终止
# 你也可以先将作业调回前台 (fg %2),然后用 Ctrl+C 终止。
# 7. 直接启动一个后台任务
ping -c 100 localhost &
# 输出:[3] 12345 (显示作业号[3]和进程ID PID)
jobs
# [3]+ Running ping -c 100 localhost &
实践练习
练习 1:基本的前后台切换
- 启动一个执行
top命令的前台进程。 - 不要退出
top,将其挂起。 - 使用
jobs命令确认它已停止。 - 将其放到后台运行。
- 将其再次调回前台,并正常退出
top。
预期输出(思路):
# 输入 top
# ... top 运行界面 ...
# 按 Ctrl+Z
# 输出: [1]+ Stopped top
$ jobs
# [1]+ Stopped top
$ bg %1
# [1]+ top &
$ jobs
# [1]+ Running top &
$ fg %1
# top 回到前台
# 在 top 界面按 q 退出
练习 2:管理多个后台作业
- 在后台启动两个长时间命令:
sleep 200 &和sleep 300 &。 - 使用
jobs命令查看它们。 - 将第二个
sleep(作业号大的那个)调回前台。 - 按下
Ctrl+Z挂起它,然后放回后台。 - 使用
kill命令终止这两个后台sleep进程。
预期输出(关键步骤):
$ sleep 200 &
[1] 11111
$ sleep 300 &
[2] 22222
$ jobs
[1]- Running sleep 200 &
[2]+ Running sleep 300 &
$ fg %2
# sleep 300 在前台运行
# 按 Ctrl+Z
[2]+ Stopped sleep 300
$ bg %2
[2]+ sleep 300 &
$ kill %1 %2
[1]- Terminated sleep 200
[2]+ Terminated sleep 300
练习 3:理解信号与进程状态
- 启动一个后台
sleep 600进程。 - 不要使用作业号,直接用
ps或pgrep找到它的PID。 - 使用
kill -STOP <PID>挂起它。 - 使用
jobs命令观察它的状态。 - 使用
kill -CONT <PID>恢复它。 - 使用
kill <PID>终止它。
预期输出(关键步骤):
$ sleep 600 &
[1] 33333
$ pgrep sleep
33333
$ kill -STOP 33333
$ jobs
[1]+ Stopped sleep 600
$ kill -CONT 33333
$ jobs
[1]+ Running sleep 600 &
$ kill 33333
[1]+ Terminated sleep 600
常见错误
- 试图用
bg启动新命令:bg和fg只作用于已经被挂起或已在后台的作业。不能用bg sleep 10来启动后台任务,正确的做法是sleep 10 &。 - 混淆作业号(Job ID)和进程号(PID):
jobs、fg、bg、kill %n使用的是Shell分配的作业号(如%1)。而系统级的ps、kill(不带%)使用的是进程PID。不要混用,例如fg 1234是错误的,应该是fg %1。 - 认为后台进程在退出终端后继续运行:这是下一课
nohup和disown解决的问题。默认情况下,当你关闭终端(或断开SSH连接),终端会向其下的所有进程(包括后台进程)发送SIGHUP信号,导致它们终止。 - 不清楚
Ctrl+Z和Ctrl+C的区别:Ctrl+Z是暂停(挂起),进程仍在内存中;Ctrl+C是终止。误按Ctrl+Z后,如果不处理,进程就静静地停在那里。 jobs命令在子Shell中无效:jobs是Shell内置命令,只显示当前Shell会话启动的作业。如果你在脚本里或另一个终端里运行jobs,看不到其他终端的作业。
小结
- 前后台是进程与终端交互的两种模式。前台独占终端,后台则不然。
- 使用
命令 &将任务放入后台运行。 - 使用
Ctrl+Z挂起前台进程,Ctrl+C终止。 - 作业控制三剑客:
jobs:查看当前Shell会话的作业列表及其状态。bg %n:将作业号为 n 的已停止作业放到后台继续运行。fg %n:将作业号为 n 的后台或已停止作业调回前台运行。
- 后台进程与启动它的终端(控制终端)紧密关联。终端关闭会导致后台进程收到
SIGHUP信号而退出。这是理解nohup和screen/tmux的基础。 - 信号(如
SIGTSTP,SIGCONT,SIGTERM)是控制进程状态的核心机制,Ctrl+Z、bg、fg、kill命令本质上都在发送特定信号。
练习编辑器
rust
Loading...