7.1 作业控制的基础

评论 0 浏览 0 2023-01-26

工作控制是指有选择地停止(暂停)进程的执行,并在以后继续(恢复)其执行的能力。用户通常通过操作系统内核的终端驱动程序和Bash共同提供的交互式界面来使用这一功能。

shell将一个job与每个管道联系起来。它保留了一个当前正在执行的作业表,可以用jobs命令列出。当Bash异步启动一个作业时,它会打印出一行字,看起来像:

[1] 25647

表示该作业是第1号作业,与该作业相关的管道中最后一个进程的进程ID是25647。单个管道中的所有进程都是同一个作业的成员。Bash使用job的抽象概念作为作业控制的基础。

为了便于实现作业控制的用户界面,操作系统保留了当前终端进程组ID的概念。这个进程组的成员(进程组ID等于当前终端进程组ID的进程)接收键盘产生的信号,如SIGINT。这些进程被说成是在前台。后台进程是指其进程组ID与终端不同的那些进程;这类进程对键盘产生的信号是免疫的。只有前台进程被允许从终端读取数据,或者,如果用户用stty tostop指定的话,被允许向终端写入数据。 试图从终端读取数据(当stty tostop生效时被写入)的后台进程会被内核的终端驱动发送一个SIGTTINSIGTTOU)信号,除非被捕获,否则会暂停该进程。

如果Bash所运行的操作系统支持作业控制,那么Bash就包含了使用它的工具。在一个进程运行时输入suspend字符(通常是‘^Z’,Control-Z)会导致该进程被停止,并将控制权返回给Bash。输入delayed suspend字符(通常是‘^Y’,Control-Y)会导致该进程在试图从终端读取输入时被停止,并将控制权返回给Bash。然后,用户可以操纵这个工作的状态,使用bg命令在后台继续工作,使用fg命令在前台继续工作,或者使用kill命令来杀死它。一个‘^Z’会立即生效,并具有导致未决输出和提前输入被丢弃的额外副作用。

在shell中,有许多方法可以指代一个作业。字符‘%’介绍了一个工作规范(jobspec)。

作业编号 n 可以称为“%n”。符号“%%”和“%+”指的是 shell 对当前作业的概念,这是在前台停止或在后台启动时的最后一个作业。单个“%”(没有随附的工作规范)也指当前作业。可以使用“%-”引用之前的作业。如果只有一个作业,‘%+’和‘%-’ 都可以用来指代那个作业。在与作业相关的输出中(例如,jobs 的输出命令),当前作业始终标记为“+”,并且以前的工作带有“-”。

还可以使用用于启动它的名称的前缀,或使用出现在其命令行中的子字符串来引用作业。例如,‘%ce’指的是命令名以‘ce’开头的已停止作业。 另一方面,使用‘%?ce’指的是任何在其命令行中含有‘ce’字符串的作业。如果前缀或子串匹配了多个作业,Bash会报告一个错误。

只需命名一个作业即可将其置于前台:‘%1’是‘fg %1’的同义词,把工作1从后台带到前台。同样,‘%1 &’在后台恢复工作1,相当于‘bg %1

每当一个作业的状态发生变化时,shell就会立即知道。通常情况下,Bash会等到要打印提示符的时候才报告作业状态的变化,这样就不会打断其他输出。 如果set内置的-b选项被激活,Bash会立即报告这种变化(参见1 Set 内置程序)。 任何SIGCHLD的陷阱都会为每个退出的子进程执行。

如果在作业停止时试图退出Bash,(或者在运行中,如果checkjobs选项被启用 – 见2 Shopt 内置程序),shell会打印一条警告信息,如果checkjobs选项被启用,会列出作业及其状态。 然后可以使用jobs命令来检查它们的状态。 如果第二次试图退出,而没有中间的命令,Bash不会再打印警告,而且任何停止的作业都被终止了。

当shell使用wait内置函数等待一个作业或进程,并且启用了作业控制,wait将在作业改变状态时返回。-f选项使wait等待,直到作业或进程终止后再返回。

最后更新2023-03-02
0 个评论
上一篇: 7 作业控制
当前页面书签