关闭父进程(终端)不会关闭特定的子进程

关闭父进程(终端)不会关闭特定的子进程

我是 Linux 新手,到目前为止,我已经了解到,如果我们通过 gnome 终端打开一个新进程,例如:gedit &“& 在后台运行它”,那么如果我们关闭终端,gedit 也会退出。所以,为了避免这种情况,我们否认这个过程通过提供 gedit 的进程 ID 从父终端。

但是,我发现了一个特点:如果我们现在从 gnome-terminal(parent) 中打开 gnome-terminal gnome-terminal &,如果我们关闭父终端,即使我没有否认子终端,子终端也不会关闭。

为什么?如果存在异常,使其成为异常的原因是什么?在哪里可以找到提到此异常的配置文件(如果可访问)?

答案1

当您关闭 GNOME 终端窗口时,shell 进程(或您指示终端运行的任何命令的进程)会收到 SIGHUP 信号。一个进程可以抓住SIGHUP,这意味着指定的函数被调用,大多数 shell 都会捕获它。 Bash 将通过向每个后台进程发送 SIGHUP 来对 SIGHUP 做出反应(除了那些已被拒绝的进程)。

查看您的示例(在和 的gedit一些帮助下): 当 GNOME 终端窗口关闭时,gedit 由 shell 发送 SIGHUP,并且由于它没有捕获 SIGHUP (并且不会忽略它),gedit 将立即退出。pstreestrace

─gnome-terminal(31486)─bash(31494)─gedit(31530)

[31486] getpgid(0x7b06) = 31494
[31486] 杀死(-31494,SIGHUP)= 0
[31494] --- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=31486, si_uid=0} ---
[31494]杀死(-31530,SIGHUP)= 0
[31530] --- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=31494, si_uid=0} ---
[31530] +++ 被 SIGHUP 杀死 +++
[31494] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED, si_pid=31530, si_status=SIGHUP} ---
[31486] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED, si_pid=31494, si_status=SIGHUP} ---

但是当你输入gnome-terminal命令并且存在一个现有的 GNOME Terminal 窗口时,默认情况下 GNOME Terminal 会做一些不寻常的事情:它会org.gnome.Terminal.Factory通过 D-Bus 调用工厂,然后立即退出; shell 看到的后台作业不会超过几分之一秒。

作为该工厂调用的结果,您在键入后获得的新窗口gnome-terminal由新线程管理相同的 GNOME 终端进程那就是管理您现有的窗口。您的第一个 shell 不知道第二个 shell 的进程 ID,并且无法自动终止它。

─gnome-terminal(9063)─┬─bash(39548)
  │ └─bash(39651)
  ├─{gnome-terminal}(9068)
  └─{gnome-terminal}(9070)

另一方面,如果您输入gnome-terminal --disable-factory &,它不会调用工厂,并且在流程方面它的行为就像gedit您的示例中一样。

──gnome-terminal(39817)──bash(39825)──gnome-terminal(39867)──bash(39874)
  │ ═─{gnome-terminal}(39868)
  └─{gnome-terminal}(39819)
关闭第一个终端窗口将同时关闭第一个和第二个终端窗口。

答案2

在这里运行 Xfce,但同样的情况也可能适用于 Gnome 终端。

如果我echo $$在两个终端窗口中运行 [编辑:然后运行ps faux] 我只看到 xfce4-terminal进程而是两个不同的bash进程,它们具有相同的父进程:xfce4-terminal进程本身。事实上,只有一个终端进程显示多个窗口。请记住,一个窗口并不一定意味着一个进程。跑去ps faux亲自看看吧。

相关内容