如何像 bash 一样暂停和恢复进程

les*_*ana 14 process signals job-control

此问题是以下问题的后续:如何暂停和恢复进程

我已经从 gnome-terminal 中的 bash 会话启动了 firefox。

进程树如下所示:

$ ps -e -o pid,ppid,cmd -H
 1828     1   gnome-terminal
26677  1828     bash
27980 26677       /bin/sh /usr/lib/firefox-3.6.15/firefox
27985 27980         /bin/sh /usr/lib/firefox-3.6.15/run-mozilla.sh /usr/lib/firefox-3.6.15/firefox-bin
27989 27985           /usr/lib/firefox-3.6.15/firefox-bin
28012 27989             /usr/lib/firefox-3.6.15/plugin-container /usr/lib/adobe-flashplugin/libflashplayer.so 27989 plugin true
Run Code Online (Sandbox Code Playgroud)

当我CTRL+Z使用 bash 时,它会暂停 Firefox。当我发出命令bg(或fg)时,它将恢复 Firefox。这正如预期的那样。

当我kill -s SIGTSTP 27980在另一个终端中发出命令时,它会[1]+ Stopped firefox在第一个终端中打印该行(就像我点击时一样CTRL+Z),但它不会挂起 firefox。我假设它只挂起 shell 脚本。

当我kill -s SIGTSTP 27989在另一个终端中发出命令(注意 PID)时,它会挂起 Firefox。第一终端没有注意到这一点。

bash 如何挂起整个进程树?它是否只是遍历树和 SIGTSTP 所有的孩子?

gee*_*aur 18

Shell 作业存在于“进程组”中;查看PGRP扩展ps输出中的列。这些用于作业控制和确定谁“拥有”终端(真实或私人)。

POSIX(取自 System V)使用负进程 ID 来指示进程组,因为进程组由组中的第一个进程(“进程组领导”)标识。因此,您将使用ps确定进程组,然后kill -s TSTP "-$pgrp". (试试ps -u"$USER" -opid,ppid,pgrp,cmd。)

在您的进程树中,进程组以firefox由启动的脚本开始bash,因此进程组将为 27980,命令将为kill -s TSTP -27980.

当然,要恢复进程组,发出kill -s CONT -- -27980.

  • 顺便说一下,当你输入 `^Z` 时,`bash` 不会执行 `SIGTSTP`;由于“firefox”的进程组是终端的当前进程组,终端驱动程序(迂腐地,线路规则)将“SIGTSTP”发送到该进程组中的所有进程。`bash` 只是对它进行 `waitpid()`(以及任何其他工作)。其他终端信号,例如`^C` 和`^\ ` 工作方式相同。(元:SE 讨厌那个 ctrl-反斜杠..) (7认同)