作业控制
100%

进程 · 第 11 课

作业控制

了解交互式 shell 如何管理前台、后台和已停止的作业。

交互式 shell 使用作业控制来协调同一终端会话中的管道。一个作业可以包含一个进程,也可以包含整条管道;这些进程通常被放进同一个进程组,以便终端和 shell 将其作为一个整体操作。

启动后台作业

在命令末尾添加 &,可以异步启动管道:

$ sleep 1000 &
[1] 18420

shell 不会等待作业结束,而是直接返回提示符。后台状态并不会自动重定向输出、脱离控制终端,也不能保证作业在退出登录后继续运行。需要时应显式重定向输入和输出;必须在交互式 shell 结束后继续运行的工作,则应使用服务管理器、调度器或终端复用器。

后台作业若试图从控制终端读取输入,通常会收到 SIGTTIN 并停止,因为它并不是终端的前台进程组。

末尾的 & 会要求交互式 shell 做什么?

列出 shell 作业

jobs 内建命令会列出当前 shell 已知的作业:

$ jobs
[1]    Running    sleep 1000 &
[2]-   Running    sleep 1001 &
[3]+   Stopped    sleep 1002

方括号中的数字是 shell 作业 ID,而不是 PID。添加 % 前缀即可组成 %1 这样的作业说明符。+ 标记表示当前作业,许多命令在未提供操作数时会选择它;- 则表示上一个作业。

由于作业表属于单个 shell,另一个终端中的 shell 通常无法通过自己的 jobsfgbg 内建命令列出或操作这些作业。

jobs 内建命令会列出什么?

停止与继续作业

作业在前台运行时,按下 Ctrl-Z 通常会让终端向其前台进程组发送 SIGTSTP。作业停止后,shell 会重新取得控制权:

$ sleep 1002
^Z
[3]+  Stopped    sleep 1002

使用以下命令,可以让当前已停止的作业在后台继续运行:

$ bg

bg 会发送继续信号,并让作业留在终端前台之外。它只对已停止的作业有用;已经在后台运行的命令不需要恢复。

bg %3 会对已停止的作业 3 做什么?

把作业移到前台

使用 fg 和作业说明符,可以让作业成为终端的前台进程组并等待它:

$ fg %1

未提供操作数时,fg 通常选择由 + 标记的当前作业。已停止的作业进入前台时会同时恢复运行。

fg %1 会做什么?

向作业发送信号

shell 允许 kill 接受作业说明符:

$ kill -TERM %1

这通常会向作业的进程组发送信号,而不只是管道中的某一个成员。应先检查选中的作业,并在考虑强制升级前使用 SIGTERM。作业说明符属于 shell 语法;脚本和外部工具更常使用核实过的 PID 或进程组 ID。

哪个操作数表示 shell 作业 1,而不是进程 ID 1?

课程已完成

你已完成 作业控制

现在,你可以有意识地在 shell 控制的不同状态之间移动作业。

  • 使用 & 启动后台作业,但不要把它误认为自动脱离终端。

  • 使用 jobs 检查当前 shell 的作业表。

  • 使用 Ctrl-Z 停止作业,再用 bg 让它在后台继续。

  • 使用 fg 把选定作业带回终端。

  • 发送信号时,用 %JOB_ID 指定 shell 作业。

保存学习进度

创建免费账户即可保存本课进度,并在任意设备上继续学习。

创建免费账户
返回 进程