Logo
Section 1 / 6

作业控制

在本课程中,你将学习什么是作业控制,以及如何在 shell 中管理和运行多个作业。

检查点

作业控制

在本课程中,你将学习什么是作业控制,以及如何在 shell 中管理和运行多个作业。

这一课的重要性

作业控制是 Bash 的核心功能,如果你每天都在使用 Bash,那么理解这一概念至关重要。

启动作业

你将学习如何使用 sleep 命令运行一个简单的作业。

输入以下命令:

1sleep 60 &
Terminal

你输入了一个“普通”命令(sleep 60),然后添加了一个字符——与号(&)。这个 & 会将命令在后台运行,从而成为当前 Bash 会话中的一个 作业。

该 作业 有两个标识符,它们会立即显示在终端中:

1[1] 39165

第一个是 作业号,这里是 1;第二个是 进程标识符,这里是 39165,但对你来说可能不同。

如果在时间结束前你执行其他命令:

1pwd

这些命令不会受到正在运行的作业干扰。你可以照常继续操作。

如果你等待程序完成(本例中为 60 秒),然后执行其他命令,Bash 会告诉你该作业的状态。例如,等待后输入:

1true

你会看到终端输出:

1[1]+ Done sleep 60

再次显示了作业号,这次附带状态(Done)以及最初运行的命令(sleep 60)。

控制作业

与启动作业类似,你也可以通过发送信号来控制作业。

现在你将启动两个作业:一个睡眠两分钟,另一个多睡一秒(以便区分它们)。

1sleep 120 & 2sleep 121 &

现在你有两个作业在后台运行。你可以使用 jobs 内建命令查看它们的状态:

1jobs

你应该看到如下输出:

1[1]- Running sleep 120 & 2[2]+ Running sleep 121 &

每个作业都用方括号中的数字标识,后面跟着加号或减号。加号表示当你运行 fg 内建命令时,该作业将被带到前台。

现在我们来做这件事:

1fg

这次你应该看到:

1sleep 121

sleep 121 进程现在在前台运行。Bash 通过将前台命令输出到终端来通知你这一点。

现在按 \C-z 发送 STOP 信号给前台进程:

1[2]+ Stopped sleep 121

再次看到作业号、加号和状态(Stopped)。如果你想让进程继续运行,需要使用 bg 内建命令:

1bg

现在你应该看到:

1[2]+ sleep 121 &

进程已从暂停状态恢复运行。如果你花超过两分钟完成上述操作,可能会收到进程已终止的消息,提示其状态为 Done。如果是这样,请重新运行两个 sleep 命令,回到此处继续。

现在两个 sleep 作业都在后台运行,你可以向它们发送其他信号。例如,可以终止它们:

1kill %1
1[1]+ Terminated: 15 sleep 120

百分号后跟数字称为 作业指定,这是告诉 Bash 操作特定作业编号的方式。当然,你也可以使用进程标识符来发送信号。

等待

在 Bash 脚本中,一种有用的技巧是启动多个后台进程,然后等待它们全部完成后再继续执行。这可以通过 wait 内建命令实现。

如果你原来的 sleep 作业仍在运行,可以运行 wait:

1wait

最终,wait 命令返回,并报告该进程的状态为 Done:

1[1]+ Done sleep 120

通常情况下,wait 总是返回退出码 0。但如果你加上作业指定,wait 会返回最后一个完成作业的退出码。

1sleep 20 & 2sleep 30 && false & 3wait %1 %2

那么这个 wait 会报告什么退出码?可以用以下命令检查:

1echo $?

挑战:如果将上面的 sleep 时间 20 和 30 互换,结果会怎样?

你学到了什么

  • 使用信号进行 作业控制

  • 作业指定 的使用

  • fg 和 bg 内建命令

  • wait 内建命令

接下来

接下来我们将学习 陷阱 和 信号。

练习

1)编写一个脚本,在后台运行一系列有用的维护或报告命令,然后在所有任务完成后输出一条总结消息。

Quiz

单选题

后台运行进程时的输出之一是

1 / 2

实战 Bash

陷阱与信号