以下是交互式 shell 中的进程组不是 shell 的工作的两种情况:
$ sleep 100 &
[1] 16081
$ jobs
[1]+ Running sleep 100 &
$ disown %1
$ jobs
$
和
$ ( sleep 200 & )
$ jobs
$
每个案例如何实现使流程组不再是一项工作?在交互式bash中,进程组成为shell的一个工作的充要条件是什么?
shell 是在伪终端从机上运行的会话领导者。当 shell 终止时,不会影响上面的两个睡眠进程,因为它们不在 shell 的作业列表中,因此不会收到 SIGHUP。然后
两个睡眠进程是否仍将 pseduoterminal 从属设备作为其会话的控制终端?
除了正常退出或者通过
kill
发送信号杀死两个睡眠进程之外,还有什么可以终止它们呢?
我想知道这两种情况与真实守护进程的效果有何不同。
答案1
在这两种情况下,进程组都是从 shell 的工作开始的。当您调用 时disown %1
,shell 会从其作业列表中删除该条目:这就是 的全部意义disown
。对于( sleep 200 & )
,该sleep
进程是由括号创建的子 shell 的工作;你可以通过运行看到这一点( sleep 200 & jobs )
。当 shell 退出时,这个任务就不再是该 shell 的工作了;与其他一切一样,子 shell 的工作是它自己的,父 shell 永远看不到它们。
这些进程保留在同一会话中,并且仍然具有相同的控制终端。这与工作控制无关。
与任何进程一样,它们可以通过退出或接收信号来终止。由于它们不是前台进程组的成员(也不可能是,因为 shell 不会将它们放回前台),因此如果终端消失,它们将不会收到内核生成的 SIGHUP。
如果进程组一开始是该 shell 的一项工作并且一直是该 shell 的一项工作,那么它就是该 shell 的一项工作。哪些命令成为单独作业的详细信息取决于 shell,超出了本答案的范围。简而言之,如果 shell 启用了作业控制(如果 shell 是交互式的,则这是默认设置),则每个复合命令都是其自己的作业。尤其:
- 管道是一个单一的作业。
- 命令或进程替换不是单独的作业,它在原始进程组中运行。
- 任何在后台运行的内容(无论是使用
&
Ctrl+Z 启动还是在后台运行)都是单独的作业。
disown
如果进程组的领导者退出,如果 shell 退出,或者如果 shell 放开它(使用),则进程组将不再是作业。