交互式 shell 使用作业控制来协调同一终端会话中的管道。一个作业可以包含一个进程,也可以包含整条管道;这些进程通常被放进同一个进程组,以便终端和 shell 将其作为一个整体操作。
进程 · 第 11 课
作业控制
了解交互式 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 通常无法通过自己的 jobs、fg 或 bg 内建命令列出或操作这些作业。
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?
可以在管理和监控 Linux 进程实验中使用 sleep 等无害命令练习这些操作。
课程已完成
你已完成 作业控制
现在,你可以有意识地在 shell 控制的不同状态之间移动作业。
使用
&启动后台作业,但不要把它误认为自动脱离终端。使用
jobs检查当前 shell 的作业表。使用
Ctrl-Z停止作业,再用bg让它在后台继续。使用
fg把选定作业带回终端。发送信号时,用
%JOB_ID指定 shell 作业。