为什么由 bash 脚本启动的进程在终端关闭后不会退出?



情况 1:

我在侏儒终端中执行sleep 1000 &,然后关闭终端。sleep进程不存在。

案例2:

下面是一个脚本t.sh

#!/usr/bin/env bash
sleep 1000 &

我在侏儒终端中执行./t.sh,然后关闭终端。sleep进程存在(ps aux已知(。难道不应该关闭这个过程吗?

使用交互式登录 shell 时,如果设置了此选项,bash 将在退出时向您的作业发送HUP信号:

juergen@samson:~ → shopt huponexit
huponexit       on

默认处理程序将终止您的进程。当启动非交互式bash(如您的脚本(时,huponexit选项是无效的。请参阅:https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html

Jürgen Hötzel在答案中所说的是正确的,但事实并非如此。

案例1:

gnome-terminal关闭时,tty(包括 pty(驱动程序将获得 tty 的连接事件,并将SIGHUP发送到与 tty 关联的控制进程。这里的控制过程是 bash,bash 将收到SIGHUP。然后,根据 bash 手册:

  • 默认情况下,外壳在收到SIGHUP后退出。 在退出之前,交互式 shell会将SIGHUP重新发送到所有正在运行或已停止的作业。 已停止的作业将SIGCONT发送,以确保它们收到SIGHUP

  • 如果huponexitshell 选项已设置为shopt,则当交互式登录 shell退出时,bash 会向所有作业发送SIGHUP

因此,对于情况 1,bash 会将SIGHUP重新发送到后台作业sleep该作业将被信号杀死(这是SIGHUP的默认行为(。

(Jürgen Hötzel 提到的huponexit选项只影响自愿退出的交互式登录 shell。但对于案例 1,bash 被SIGHUP杀死。而且,在 gnome-terminal 中运行的 bash 不一定是登录shell,尽管它实际上是一个交互式 shell

案例2:

这里涉及 2 个 bash 过程:

  • bash#1:在 gnome 终端中运行的 bash 进程。
  • bash#2:运行t.sh脚本的 bash 进程。

t.sh(bash#2( 运行时,sleep 1000 &作为 bash#2 的后台作业启动。t.sh(bash#2( 退出后,sleep将继续运行,但它将成为孤立进程,init进程将处理它,sleep的 PPID 将变为 1(init进程的 PID(。

当 gnome 终端关闭时,bash#1 将收到SIGHUP,bash#1 将重新发送SIGHUP到它的所有作业。但是sleep不是 bash#1 的工作,因此sleep不会收到SIGHUP,因此它将在 bash#1 完成后继续运行。

简单来说,没有。使用"&",您正在使当前进程作为后台进程运行。据我所知,你必须明确杀死它。

相关内容

  • 没有找到相关文章

最新更新