我是 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 将立即退出。pstree
strace
─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
亲自看看吧。