今天我观察到一些事情,可能有一个简单的解释,但对我来说却是非常出乎意料的:我正在运行 CentOS(以及行为相同的 RHEL)。我在终端中打开 bash 并启动任何子进程,例如 gedit。窗户打开了,很好。当我执行“ps”时,我可以看到 gedit 具有 bash 作为其父进程,而 bash 本身具有 gnome-terminal 作为其父进程。当我停止 bash 时,我希望所有子进程也会停止。但是gedit继续运行并且parent变成了1(init)!
我尝试不优雅地停止 shell,而是用力杀死它,结果相同。它尝试杀死终端而不是外壳,结果仍然相同。仅当我通过单击 X 按钮关闭终端时,gedit 也会关闭。
我没想到会有这种行为。用 nohup 启动 gedit,我不会感到惊讶,但即使没有 nohup ...为什么它还活着?
也许有人可以阐明一些情况并知道那里发生了什么。提前致谢!
答案1
gedit、gvim、google-chrome 等程序会自动将自己分叉到后台。这允许您输入
gedit /home/msw/ul-answer
映射新窗口并恢复 shell 提示符。这不是一个糟糕的设计选择,并且通常有一个选项可以覆盖它。这些命令gedit -w
不会gvim --nofork
与控制终端分离,也不会返回 shell 提示符。
对于一个程序来说,它本身会在后台运行,它会分叉,然后父进程退出。这将使您的正常 gedit 实例在您键入后几乎立即成为 init (PPID == 1) 的子级。
其他程序(例如 mplayer 或 calibre)不会自动进入后台,因为它们不经常键入,或者因为它们喜欢将调试信息转储到控制终端。
增加了奇怪之处:
在花了一点时间测试并查看 strace 输出等之后,gedit 似乎不会自动后台运行。我所说的关于 gvim 的内容仍然有效,而且已经过了睡觉的时间了,所以我现在就这样吧。
答案2
当您关闭终端窗口时,内核会发送一个叹息发出猛击信号。然后 Bash 向每个作业发送一个 SIGHUP,因此它会通过 SIGHUP 杀死 gedit。
当您通过键入exit
或Ctrl+D或通过使用 SIGKILL 终止 bash 来退出 bash 时,终端模拟器会注意到其子进程已退出并关闭窗口。 Gedit 不受影响。